BZOJ4154——IPSC2015 Generating Synergy

来源:互联网 发布:wpf 数据绑定 编辑:程序博客网 时间:2024/06/02 05:20

题意:AC通道
题解:
这题有个十分巧妙的解法。
因为有子树修改,而又不是整棵子树的修改,直接上dfs序是不行的。
考虑它每次修改的只有子节点,而且有距离限制,我们想到这是与点的深度有关的问题。
于是我们把树上的点抽象到二维平面上,横坐标为其dfs序,纵坐标为其深度,这样每次的修改就对应一个区域的染色操作,这东西用kdtree可以随便搞,弄个lazytag就可以了。

一堆调试用的代码,所以看起来很长。

#include <bits/stdc++.h>//#include <conio.h>using namespace std;typedef long long ll;typedef double db;const int inf=0x3f3f3f3f;int getint(){    int f=1,g=0;char c=getchar();    while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}    while(c>='0' && c<='9')g=(g<<3)+(g<<1)+c-'0',c=getchar();    return f*g;}const int maxn=100005;const int mod=1000000007;int dim;int n,m;struct node{    int d[2];    int max[2];    int min[2];    int l,r;    int tag;    int color;    int& operator [] (const unsigned int& num)    {        return d[num];    }    bool operator < (const node& no)const     {        return d[dim]<no.d[dim];    }       bool operator == (const node& no)const     {        return d[0]==no.d[0] && d[1]==no.d[1];    }};node p[maxn];int root;struct Kdtree{    node t[maxn];    #define lc t[x].l    #define rc t[x].r    #define ls t[t[x].l]    #define rs t[t[x].r]    void update(int x)    {        t[x].min[0]=t[x].max[0]=t[x][0];        t[x].min[1]=t[x].max[1]=t[x][1];        if(lc)        {            t[x].min[0]=min(t[x].min[0],ls.min[0]);            t[x].max[0]=max(t[x].max[0],ls.max[0]);            t[x].min[1]=min(t[x].min[1],ls.min[1]);            t[x].max[1]=max(t[x].max[1],ls.max[1]);        }        if(rc)        {            t[x].min[0]=min(t[x].min[0],rs.min[0]);            t[x].max[0]=max(t[x].max[0],rs.max[0]);            t[x].min[1]=min(t[x].min[1],rs.min[1]);            t[x].max[1]=max(t[x].max[1],rs.max[1]);        }    }    void push_down(int x)    {        if(!x || !t[x].tag)return;        t[x].color=t[x].tag;        ls.tag=rs.tag=t[x].tag;        t[x].tag=0;    }    #define mid (l+r>>1)    int build(int l,int r,int now)    {        dim=now;        nth_element(p+l,p+mid,p+r+1);        int x=mid;        t[x].color=1;        for(int i=0;i<2;i++)        {            t[x].min[i]=t[x].max[i]=t[x][i]=p[x][i];        }        if(l<mid)lc=build(l,mid-1,now^1);        if(r>mid)rc=build(mid+1,r,now^1);        update(x);        return x;    }    #undef mid    node T1,T2;    int col;    void setcolor(int x)    {        if(!x)return;        push_down(x);        if(t[x].min[0]>T2[0] || t[x].max[0]<T1[0] || t[x].min[1]>T2[1] || t[x].max[1]<T1[1])return;        if(t[x].min[0]>=T1[0] && t[x].max[0]<=T2[0] && t[x].min[1]>=T1[1] && t[x].max[1]<=T2[1])        {            t[x].tag=col;            return;        }        if(t[x][0]>=T1[0] && t[x][0]<=T2[0] && t[x][1]>=T1[1] && t[x][1]<=T2[1])t[x].color=col;        setcolor(lc);setcolor(rc);    }    node T;    int getcolor(int x)    {        push_down(x);        if(T[0]<t[x].min[0] || T[0]>t[x].max[0] || T[1]<t[x].min[1] || T[1]>t[x].max[1])return 0;        if(t[x]==T)return t[x].color;        return getcolor(lc)+getcolor(rc);    }    void set(int x,int y,int xx,int yy,int co)    {        T1[0]=x;T1[1]=y;        T2[0]=xx;T2[1]=yy;        col=co;        setcolor(root);    }    int query(int x,int y)    {        T[0]=x;T[1]=y;        return getcolor(root);    }    void init()    {        memset(t,0,sizeof t);        memset(p,0,sizeof p);        root=0;    }       void run(int x)    {        if(!x)return;        run(lc);        printf("(%d,%d)->(%d,%d):%d(%d)(%d,%d)\n",t[x].min[0],t[x].min[1],t[x].max[0],t[x].max[1],t[x].color,t[x].tag,t[x][0],t[x][1]);        run(rc);    }    #undef lc    #undef rc    #undef ls    #undef rs}kdtree;vector<int> g[maxn];void addedge(int from,int to){    g[from].push_back(to);    g[to].push_back(from);}int dep[maxn];int st[maxn];int ed[maxn];int ind;int father[maxn];void dfs(int x){    st[x]=++ind;    for(int i=0;i<g[x].size();i++)    {        int to=g[x][i];        if(father[x]==to)continue;        dep[to]=dep[x]+1;        dfs(to);    }    ed[x]=ind;}int main(){//  freopen("in.txt","r",stdin);    int T=getint();    while(T--)    {        for(int i=0;i<maxn;i++)g[i].clear();        kdtree.init();        ind=0;        n=getint();        int temp=getint();        m=getint();        for(int i=2;i<=n;i++)        {            father[i]=getint();            addedge(i,father[i]);        }        dep[1]=1;        dfs(1);        /*        for(int i=1;i<=n;i++)        {            printf("%d ",st[i]);        }        puts("");        for(int i=1;i<=n;i++)        {            printf("%d ",ed[i]);        }        puts("");        for(int i=1;i<=n;i++)        {            printf("%d ",dep[i]);        }        puts("");        */        for(int i=1;i<=n;i++)        {            p[i][0]=st[i];            p[i][1]=dep[i];        }        root=kdtree.build(1,n,0);        /*        kdtree.run(root);            puts("");            getch();        */        int x,y;        int opt;        ll ans=0;        for(int i=1;i<=m;i++)        {            x=getint();            y=getint();            opt=getint();            if(!opt)            {                ll t=kdtree.query(st[x],dep[x]);                //printf("%d\n",t);                ans+=(ll)t*(ll)i;                ans%=mod;            }            else            {                /*                printf("We are painting (%d,%d)->(%d,%d):%d\n",st[x],dep[x],ed[x],dep[x]+y,opt);                getch();                */                kdtree.set(st[x],dep[x],ed[x],dep[x]+y,opt);            }            /*            kdtree.run(root);            puts("");            getch();            */        }        printf("%d\n",ans);         }    return 0;}
0 0
原创粉丝点击