CF D1 wa pretest #4 求调,玄1小号关注
  • 板块学术版
  • 楼主Windy_YY
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/8/12 01:36
  • 上次更新2024/8/12 09:21:47
查看原帖
CF D1 wa pretest #4 求调,玄1小号关注
378467
Windy_YY楼主2024/8/12 01:36
#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=331080;
int depx[N],b[N];
vector<int>z[N];
int top[N], to[N], back[N], w[N], sz[N], dep[N], a[N], idx, fat[N], RS[N], RSUM[N];
// top[i]: i 链的顶端
// to[i]: 原 i 点对应的点
// back[i]: 现 i 点对应的点
// w[i]: 现 i 点对应的权值
void dfs1(int u, int fa) {
    sz[u] = 1, dep[u] = dep[fa] + 1, fat[u] = fa;
    for (auto &v : z[u]) if (v != fa) dfs1(v, u), sz[u] += sz[v];
}
void dfs2(int u, int hd, int fa) {
    idx++, back[idx] = u, to[u] = idx, top[u] = hd, w[idx] = b[u]; int heavy = -1;
    for (auto &v : z[u]) if (v != fa) if (heavy == -1 || sz[heavy] < sz[v]) heavy = v;
    if (~heavy) dfs2(heavy, hd, u);
    for (auto &v : z[u]) if (v != fa && v != heavy) dfs2(v, v, u);
}
namespace Sgt {
struct Node {
    int l, r, sum, tag;
    void init(int p) { l = r = p, sum = w[p], tag = 0; }
    void color(int v) { sum += (r - l + 1) * v, tag += v; }
} zz[N << 2];
Node operator+(const Node &l, const Node &r) {
    Node res;
    res.l = l.l, res.r = r.r;
    res.sum = (l.sum + r.sum), res.tag = 0;
    return res;
}
void build(int l, int r, int rt) {
    if (l == r) return zz[rt].init(l);
    int mid = l + r >> 1; build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
    zz[rt] = zz[rt << 1] + zz[rt << 1 | 1];
}
void pud(int rt) { if (zz[rt].tag) zz[rt << 1].color(zz[rt].tag), zz[rt << 1 | 1].color(zz[rt].tag), zz[rt].tag = 0; }
void modify(int l, int r, int rt, int ll, int rr, int v) {
    if (ll <= l && r <= rr) return zz[rt].color(v);
    int mid = l + r >> 1; pud(rt);
    if (ll <= mid) modify(l, mid, rt << 1, ll, rr, v);
    if (mid < rr) modify(mid + 1, r, rt << 1 | 1, ll, rr, v);
    zz[rt] = zz[rt << 1] + zz[rt << 1 | 1];
}
int query(int l, int r, int rt, int ll, int rr) {
    if (ll <= l && r <= rr) return zz[rt].sum;
    int mid = l + r >> 1, s = 0; pud(rt);
    if (ll <= mid) s += query(l, mid, rt << 1, ll, rr);
    if (mid < rr) s += query(mid + 1, r, rt << 1 | 1, ll, rr);
    return s;
}
}
int n,m,S[N];
void modifyTree(int rt, int v) { Sgt::modify(1, n, 1, to[rt], to[rt] + sz[rt] - 1, v); }
int queryTree(int rt) { return Sgt::query(1, n, 1, to[rt], to[rt] + sz[rt] - 1); }
void modifyP(int rt, int v) { Sgt::modify(1, n, 1, to[rt], to[rt], v); }
int queryP(int rt) { return Sgt::query(1, n, 1, to[rt], to[rt]); }
//RS[i] 真正每一子树的值
//RSUM[i] 真正每一层的值
//S[i] 现在每一层的值
void dfs(int u,int fa){
    RS[u]=u;
    for(auto&v:z[u])
        if(v!=fa)dfs(v,u),RS[u]+=RS[v];
}
int idxx=0;
int dfnn[N];
void awv(int u,int depth){
    if(u>n)return;
    depx[++idxx]=depth;
    dfnn[idxx]=u;
    b[u]=a[idxx];
    awv(u<<1,depth+1);
    awv(u<<1|1,depth+1);
}
signed main(){
    // ios_base::sync_with_stdio(0);
    // cin.tie(0);
    int T;
    cin>>T;
    while(T--){
        cin>>n>>m;int cx=0;idxx=0;idx=0;
        for(int i=1;i<=n;++i)to[i]=back[i]=top[i]=sz[i]=w[i]=a[i]=fat[i]=0;
        for(int i=1;i<=n;++i)z[i].clear();
        for(int i=1;i<n;++i){int x;cin>>x;z[i+1].pb(x),z[x].pb(i+1);}
        for(int i=1;i<=n;++i)cin>>a[i];
        for(int i=0;i<=(n<<2);++i)Sgt::zz[i].l=Sgt::zz[i].r=Sgt::zz[i].sum=Sgt::zz[i].tag=0;
        awv(1,1);
        for(int i=1;i<=n;++i)S[i]=RSUM[i]=0;
        for(int i=1;i<=n;++i)
            S[depx[i]]+=a[i],cx=max(cx,depx[i]);
        for(int i=1;i<=cx;++i){
            int L=(1ll<<(i-1)),R=(1ll<<i)-1,len=R-L+1;
            RSUM[i]=(L+R)*len/2;
        }
        dfs1(1,0),dfs2(1,1,0),Sgt::build(1,n,1);
        dfs(1,0);
        while(m--){
            int x,y;cin>>x>>y;
            S[depx[x]]-=a[x]-a[y];
            S[depx[y]]-=a[y]-a[x];
            modifyP(dfnn[x],a[y]-a[x]);
            modifyP(dfnn[y],a[x]-a[y]);
            // cout<<"xiu "<<x<<' '<<a[y]<<' '<<a[x]<<'\n';
            swap(a[x],a[y]);
            int ok=1;
            for(int i=1;i<=cx;++i)
                if(S[i]!=RSUM[i]){ok=0;break;}
            if(ok){
                int v1=queryTree(2),v2=queryTree(3);
                // cout<<"qwq "<<v1<<' '<<v2<<' '<<RS[2]<<' '<<RS[3]<<'\n';
                if(v1==RS[2]&&v2==RS[3]||v1==RS[3]&&v2==RS[2])cout<<"YES\n";
                else cout<<"NO\n";
            }else cout<<"NO\n";
        }
    }
    return 0;
} // main
/*
1
1
999999998 1000000000
999999999 999999999 1 1
*/
2024/8/12 01:36
加载中...