Wc2014 紫荆花之恋
Posted AntiLeaf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wc2014 紫荆花之恋相关的知识,希望对你有一定的参考价值。
哈哈哈哈哈哈哈哈哈哈哈哈我终于过了!!!!!!!!!!!!!!!
从昨天上午就开始写了,下午回家之后调了一会儿没什么感觉,就删了重打了一遍,然后调了一晚上+今天半个上午......我*******终于过了......
一道极其恶心的动态树分治......
首先点分治,限制条件就变成了di+dj<=ri+rj,移项得rj-dj>=di-ri,对重心和子树开平衡树维护di-ri即可。
查询的时候先跳点分治树更新答案,然后逐层把di-ri插入平衡树,上跳的过程中判断是否有子树失衡(某个子树大于子树总大小的alpha倍),有则提出来暴力重构成完全平衡的点分治树。
各种坑爹细节和脑残错误调了一天,不过还是过了,激动......
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 const int maxn=100010; 7 const double alpha=0.7; 8 struct node{ 9 static int randint(){ 10 static int a=1213,b=97818217,p=998244353,x=751815431; 11 x=a*x+b;x%=p; 12 return x<0?(x+=p):x; 13 } 14 int data,size,p; 15 node *ch[2]; 16 node(int d):data(d),size(1),p(randint()){} 17 inline void refresh(){size=ch[0]->size+ch[1]->size+1;} 18 }*null=new node(0),*root[maxn],*root1[maxn][50]; 19 void addnode(int,int); 20 void rebuild(int,int,int,int); 21 void dfs_getcenter(int,int,int&); 22 void dfs_getdis(int,int,int,int); 23 void dfs_destroy(int,int); 24 void insert(int,node*&); 25 int order(int,node*); 26 void destroy(node*&); 27 void rot(node*&,int); 28 vector<int>G[maxn],W[maxn]; 29 int size[maxn]={0},siz[maxn][50]={0},son[maxn]; 30 bool vis[maxn]; 31 int depth[maxn],p[maxn],d[maxn][50],id[maxn][50]; 32 int n,m,w[maxn],tmp; 33 long long ans=0; 34 int main(){ 35 null->size=0; 36 null->ch[0]=null->ch[1]=null; 37 scanf("%*d%d",&n); 38 fill(vis,vis+n+1,true); 39 fill(root,root+n+1,null); 40 for(int i=0;i<=n;i++)fill(root1[i],root1[i]+50,null); 41 scanf("%*d%*d%d",&w[1]); 42 insert(-w[1],root[1]); 43 size[1]=1; 44 printf("0\\n"); 45 for(int i=2;i<=n;i++){ 46 scanf("%d%d%d",&p[i],&tmp,&w[i]); 47 p[i]^=(ans%(int)1e9); 48 G[i].push_back(p[i]); 49 W[i].push_back(tmp); 50 G[p[i]].push_back(i); 51 W[p[i]].push_back(tmp); 52 addnode(i,tmp); 53 printf("%lld\\n",ans); 54 } 55 return 0; 56 } 57 void addnode(int x,int z){//wj-dj>=di-wi 58 depth[x]=depth[p[x]]+1; 59 size[x]=1; 60 insert(-w[x],root[x]); 61 int rt=0; 62 for(int u=p[x],k=depth[p[x]];u;u=p[u],k--){ 63 if(u==p[x]){ 64 id[x][k]=x; 65 d[x][k]=z; 66 } 67 else{ 68 id[x][k]=id[p[x]][k]; 69 d[x][k]=d[p[x]][k]+z; 70 } 71 ans+=order(w[x]-d[x][k],root[u])-order(w[x]-d[x][k],root1[id[x][k]][k]); 72 insert(d[x][k]-w[x],root[u]); 73 insert(d[x][k]-w[x],root1[id[x][k]][k]); 74 size[u]++; 75 siz[id[x][k]][k]++; 76 if(siz[id[x][k]][k]>size[u]*alpha+5)rt=u; 77 } 78 id[x][depth[x]]=0; 79 d[x][depth[x]]=0; 80 if(rt){ 81 dfs_destroy(rt,depth[rt]); 82 rebuild(rt,depth[rt],size[rt],p[rt]); 83 } 84 } 85 void rebuild(int x,int k,int s,int pr){ 86 int u=0; 87 dfs_getcenter(x,s,u); 88 vis[x=u]=true; 89 p[x]=pr; 90 depth[x]=k; 91 size[x]=s; 92 d[x][k]=id[x][k]=0; 93 destroy(root[x]); 94 insert(-w[x],root[x]); 95 if(s<=1)return; 96 for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]){ 97 p[G[x][i]]=0; 98 d[G[x][i]][k]=W[x][i]; 99 siz[G[x][i]][k]=p[G[x][i]]=0; 100 destroy(root1[G[x][i]][k]); 101 dfs_getdis(G[x][i],x,G[x][i],k); 102 } 103 for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]])rebuild(G[x][i],k+1,size[G[x][i]],x); 104 } 105 void dfs_getcenter(int x,int s,int &u){ 106 size[x]=1; 107 son[x]=0; 108 for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]&&G[x][i]!=p[x]){ 109 p[G[x][i]]=x; 110 dfs_getcenter(G[x][i],s,u); 111 size[x]+=size[G[x][i]]; 112 if(size[G[x][i]]>size[son[x]])son[x]=G[x][i]; 113 } 114 if(!u||max(s-size[x],size[son[x]])<max(s-size[u],size[son[u]]))u=x; 115 } 116 void dfs_getdis(int x,int u,int rt,int k){ 117 insert(d[x][k]-w[x],root[u]); 118 insert(d[x][k]-w[x],root1[rt][k]); 119 id[x][k]=rt; 120 siz[rt][k]++; 121 size[x]=1; 122 for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]&&G[x][i]!=p[x]){ 123 p[G[x][i]]=x; 124 d[G[x][i]][k]=d[x][k]+W[x][i]; 125 dfs_getdis(G[x][i],u,rt,k); 126 size[x]+=size[G[x][i]]; 127 } 128 } 129 void dfs_destroy(int x,int k){ 130 vis[x]=false; 131 for(int i=0;i<(int)G[x].size();i++)if(depth[G[x][i]]>=k&&G[x][i]!=p[x]){ 132 p[G[x][i]]=x; 133 dfs_destroy(G[x][i],k); 134 } 135 } 136 void insert(int x,node *&rt){ 137 if(rt==null){ 138 rt=new node(x); 139 rt->ch[0]=rt->ch[1]=null; 140 return; 141 } 142 int d=x>=rt->data; 143 insert(x,rt->ch[d]); 144 rt->refresh(); 145 if(rt->ch[d]->p<rt->p)rot(rt,d^1); 146 } 147 int order(int x,node *rt){ 148 int ans=0,d; 149 x++; 150 while(rt!=null){ 151 if((d=x>rt->data))ans+=rt->ch[0]->size+1; 152 rt=rt->ch[d]; 153 } 154 return ans; 155 } 156 void destroy(node *&x){ 157 if(x==null)return; 158 destroy(x->ch[0]); 159 destroy(x->ch[1]); 160 delete x; 161 x=null; 162 } 163 void rot(node *&x,int d){ 164 node *y=x->ch[d^1]; 165 x->ch[d^1]=y->ch[d]; 166 y->ch[d]=x; 167 x->refresh(); 168 (x=y)->refresh(); 169 } 170 /* 171 Wc2014 紫荆花之恋 172 di+dj<=wi+wj,移项得wj-dj>=di-wi,动态点分治维护即可。 173 每个重心和子树存一棵平衡树维护di-wi,加点的时候跳点分治树更新答案后加入新点, 174 加入之后判断子树是否失衡,找出最高的失衡节点,把整个子树暴力重构成完全平衡的点分治树。 175 */
以上是关于Wc2014 紫荆花之恋的主要内容,如果未能解决你的问题,请参考以下文章