BZOJ4154 [Ipsc2015]Generating Synergy

来源:互联网 发布:境外电视直播软件apk 编辑:程序博客网 时间:2024/06/06 10:08

每个点变成二维平面上一个点,横坐标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-8struct 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;} /*14 3 71 2 23 0 02 1 33 0 01 0 22 0 04 1 14 0 0 */


0 0
原创粉丝点击