BZOJ4154 [Ipsc2015]Generating Synergy

每个点变成二维平面上一个点,横坐标dfn纵坐标dep,这样就变成了矩形染色单点查询。

正解是kdt?然而不会啊,好在内存卡的不是很紧,二维线段树动态开点就可以过了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<ctime>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<bitset>
#include<map>
using namespace std;
#define MAXN 100010
#define MAXM 27600010
#define INF 1000000000
#define MOD 1000000007
#define ll long long
#define eps 1e-8
struct vec{
    int to;
    int fro;
};
char ch,B[1<<10],*S=B,*TT=B;
#define getc() (S==TT&&(TT=(S=B)+fread(B,1,1<<10,stdin),S==TT)?0:*S++)
inline int read()
{
int x=0,f=1;char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
vec mp[MAXN];
int tai[MAXN],cnt;
int n,m,c;
int tot;
int son[MAXM][2],col[MAXM],vis[MAXM];
int rt[MAXN*4];
int dep[MAXN],dfn[MAXN],fa[MAXN],tim;
int siz[MAXN];
int T;
inline void be(int x,int y){
    mp[++cnt].to=y;
    mp[cnt].fro=tai[x];
    tai[x]=cnt;
}
void ins2(int &x,int y,int z,int p){
    if(!x){
        x=++tot;
        son[x][0]=son[x][1]=0;
        vis[x]=0;
        col[x]=0;
    }
    if(y==z){
        col[x]=1;
        vis[x]=T;
        return ;
    }
    int mid=y+z>>1;
    if(p<=mid){
        ins2(son[x][0],y,mid,p);
    }else{
        ins2(son[x][1],mid+1,z,p);
    }
}
void ins1(int x,int y,int z,int p1,int p2){
    ins2(rt[x],1,n,p2);
    if(y==z){
        return ;
    }
    int mid=y+z>>1;
    if(p1<=mid){
        ins1(x<<1,y,mid,p1,p2);
    }else{
        ins1(x<<1|1,mid+1,z,p1,p2);
    }
}
void dfs(int x){
    int i,y;
    dep[x]=dep[fa[x]]+1;
    dfn[x]=++tim;
    siz[x]=1;
    ins1(1,1,n,dfn[x],dep[x]);
    for(i=tai[x];i;i=mp[i].fro){
        y=mp[i].to;
        dfs(y);
        siz[x]+=siz[y];
    }
}
void change2(int x,int y,int z,int l,int r,int cv){
    if(!x){
        return ;
    }
    if(y==l&&z==r){
        col[x]=cv;
        vis[x]=T;
        return ;
    }
    int mid=y+z>>1;
    if(r<=mid){
        change2(son[x][0],y,mid,l,r,cv);
    }else if(l>mid){
        change2(son[x][1],mid+1,z,l,r,cv);
    }else{
        change2(son[x][0],y,mid,l,mid,cv);
        change2(son[x][1],mid+1,z,mid+1,r,cv);
    }
}
void change1(int x,int y,int z,int l,int r,int l2,int r2,int cv){
    if(y==l&&z==r){
        change2(rt[x],1,n,l2,r2,cv);
        return ;
    }
    int mid=y+z>>1;
    if(r<=mid){
        change1(x<<1,y,mid,l,r,l2,r2,cv);
    }else if(l>mid){
        change1(x<<1|1,mid+1,z,l,r,l2,r2,cv);
    }else{
        change1(x<<1,y,mid,l,mid,l2,r2,cv);
        change1(x<<1|1,mid+1,z,mid+1,r,l2,r2,cv);
    }
}
int anst,ansc;
void ask2(int x,int y,int z,int p){
    if(!x){
        return ;
    }
    if(vis[x]>anst){
        ansc=col[x];
        anst=vis[x];
    }
    if(y==z){
        return ;
    }
    int mid=y+z>>1;
    if(p<=mid){
        ask2(son[x][0],y,mid,p);
    }else{
        ask2(son[x][1],mid+1,z,p);
    }
}
void ask1(int x,int y,int z,int p1,int p2){
    ask2(rt[x],1,n,p2);
    if(y==z){
        return ;
    }
    int mid=y+z>>1;
    if(p1<=mid){
        ask1(x<<1,y,mid,p1,p2);
    }else{
        ask1(x<<1|1,mid+1,z,p1,p2);
    }
}
int main(){
    int i,x,y,z,o;
    int tmp;
//  freopen("g1.in","r",stdin);
    tmp=read();
    while(tmp--){
        cnt=0;
        tot=0;
        ll ans=0;
        tim=0;
        memset(rt,0,sizeof(rt));
        memset(tai,0,sizeof(tai));
        n=read();
        c=read();
        m=read();
        for(i=2;i<=n;i++){
            x=read();
            fa[i]=x;
            be(x,i);
        }
        T=1;
        dfs(1);
        for(i=1;i<=m;i++){
            x=read();
            y=read();
            o=read();
            if(!o){
                anst=0;
                ask1(1,1,n,dfn[x],dep[x]);
                ans+=(ll)((ll)i*ansc)%MOD;
                ans%=MOD;
                //cout<<ansc<<endl;
            }else{
                T++;
                change1(1,1,n,dfn[x],dfn[x]+siz[x]-1,dep[x],dep[x]+y,o);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
 
/*
1
4 3 7
1 2 2
3 0 0
2 1 3
3 0 0
1 0 2
2 0 0
4 1 1
4 0 0
 
*/


你可能感兴趣的:(BZOJ4154 [Ipsc2015]Generating Synergy)