您的位置:首页 > 其它

BZOJ 4154 [Ipsc2015]Generating Synergy(KD-Tree)

2017-08-07 18:30 531 查看

题目链接:BZOJ 4154 [Ipsc2015]Generating Synergy

题意:

给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色。

题解:

将dfs序看为x,dep看为y,那么就是一个在二维平面上的操作了。

由于这个平面范围比较大,二维线段树不好开,然后kd-tree搞搞。

1 #include<cstdio>
2 #include<algorithm>
3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
4 using namespace std;
5
6 namespace KD_Tree{
7     const int N=1e5+7,DI=2;
8     struct Node{
9         int p[DI],f,l,r,mx[DI],mi[DI],tim,col,t,c;
10         int operator[](const int&idx)const{return p[idx];}
11         void in(int idx,int *v){f=idx,tim=t=0,c=col=1;F(i,0,DI-1)p[i]=v[i];}
12         void up(Node&a){
13             F(i,0,DI-1){
14                 mi[i]=min(mi[i],a.mi[i]);
15                 mx[i]=max(mx[i],a.mx[i]);
16             }
17         }
18     }T
;
19     int idx
,cmpd,root;
20
21     bool cmp(const Node&a,const Node&b){return a[cmpd]<b[cmpd];}
22     void up(int x){
23         if(T[x].l)T[x].up(T[T[x].l]);
24         if(T[x].r)T[x].up(T[T[x].r]);
25     }
26     int build(int l,int r,int d=0,int f=0)
27     {
28         int mid=l+r>>1;
29         cmpd=d%DI,nth_element(T+l,T+mid,T+r+1,cmp);
30         idx[T[mid].f]=mid,T[mid].f=f;
31         F(i,0,DI-1)T[mid].mi[i]=T[mid].mx[i]=T[mid][i];
32         T[mid].l=l!=mid?build(l,mid-1,d+1,mid):0;
33         T[mid].r=r!=mid?build(mid+1,r,d+1,mid):0;
34         return up(mid),mid;
35     }
36     void update(int x1,int x2,int y1,int y2,int t,int c,int rt=root)
37     {
38         if(T[rt].mi[0]>=x1&&T[rt].mx[0]<=x2&&T[rt].mi[1]>=y1&&T[rt].mx[1]<=y2)
39         {
40             T[rt].tim=t,T[rt].col=c;
41             T[rt].t=t,T[rt].c=c;
42             return;
43         }
44         if(T[rt].mx[0]<x1||T[rt].mi[0]>x2||T[rt].mx[1]<y1||T[rt].mi[1]>y2)
45             return;
46         if(T[rt][0]>=x1&&T[rt][0]<=x2&&T[rt][1]>=y1&&T[rt][1]<=y2)
47             T[rt].tim=t,T[rt].col=c;
48         if(T[rt].l)update(x1,x2,y1,y2,t,c,T[rt].l);
49         if(T[rt].r)update(x1,x2,y1,y2,t,c,T[rt].r);
50     }
51     int ask(int rt)
52     {
53         int t=T[rt].tim,c=T[rt].col;
54         while(T[rt].f)
55         {
56             rt=T[rt].f;
57             if(T[rt].t>t)t=T[rt].t,c=T[rt].c;
58         }
59         return c;
60     }
61 };
62 const int N=1e5+7,P=1e9+7;
63 int t,n,q,g
,v
,nxt
,ed,c;
64 int x,in
,out
,cnt,dep
,ans;
65
66 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
67
68 void dfs(int x,int d=0)
69 {
70     in[x]=++cnt,dep[x]=d;
71     for(int i=g[x];i;i=nxt[i])dfs(v[i],d+1);
72     out[x]=++cnt;
73 }
74
75 using namespace KD_Tree;
76 int main(){
77     scanf("%d",&t);
78     while(t--)
79     {
80         scanf("%d%d%d",&n,&c,&q);
81         F(i,1,n)g[i]=0;ed=0;
82         F(i,2,n)scanf("%d",&x),adg(x,i);
83         ans=0,cnt=0,dfs(1);
84         F(i,1,n)
85         {
86             int x[2];
87             x[0]=in[i],x[1]=dep[i];
88             T[i].in(i,x);
89         }
90         root=build(1,n);
91         F(i,1,q)
92         {
93             int a,l,c;
94             scanf("%d%d%d",&a,&l,&c);
95             if(c)update(in[a],out[a],dep[a],dep[a]+l,i,c);
96             else
97             {
98                 int tmp=ask(idx[a]);
99                 ans=(ans+1ll*tmp*i)%P;
100             }
101         }
102         printf("%d\n",ans);
103     }
104     return 0;
105 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: