bzoj3435 [Wc2014]紫荆花之恋

如果这棵树不变的话,就是一个裸的点分树套平衡树,式子也很好推$di+dj<=ri+rj$,$ri-di>=dj-rj$ 平衡树维护$dj-rj$,然后查$ri-di$的$rank$即可。

但是点分树如果极度不平衡也就没有什么意义了。所以利用替罪羊树的思想,当某个子树极度不平衡时,就重新找重心,重建点分树。时间复杂度$O(nlg^2n)$,无旋Treap被卡,有旋Treap常数十分优秀。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 #define L 1<<20
  8 char _buf[L],*SS,*TT,c; 
  9 const int BufS=3000000,md=1000000000;
 10 char buf[BufS],*inss=buf,*outs=buf,num[10];
 11 inline void pl(register long long a){
 12     if(!a){*outs++='0',*outs++='\n';return;}
 13     register int tp=0;while(a)num[tp++]=a%10,a/=10;
 14     while(tp--)*outs++=num[tp]+'0';*outs++='\n';    
 15 }
 16 #define gc() (SS==TT&&(TT=(SS=_buf)+fread(_buf,1,L,stdin),SS==TT)?0:*SS++)
 17 int get()
 18 {
 19     for(c=gc();c<'0'||c>'9';c=gc());
 20     int x=c^'0';
 21     for(c=gc();c>='0'&&c<='9';c=gc())x=x*10+(c^'0');
 22     return x;
 23 }
 24 #define N 100050
 25 int n;
 26 long long ans;
 27 namespace Treap{
 28     #define tp pair<Node*,Node*>
 29     struct Node{
 30         Node *ch[2];
 31         int key,val,size;
 32         void pushup(){
 33             size=ch[0]->size+ch[1]->size+1;
 34         }
 35         Node(int k);
 36     }*null=new Node(0),*root[N],*root1[N];
 37     Node :: Node(int k){
 38         key=k;val=rand();size=1;
 39         ch[0]=ch[1]=null;
 40     }
 41     void init(){
 42         null->ch[0]=null->ch[1]=null;
 43         null->key=null->val=null->size=0;
 44         for(int i=0;i<=::n;i++)root[i]=root1[i]=null;
 45     }
 46     int getrank(Node *now,int x){
 47         int ans=0;
 48         while(now!=null){
 49             if(now->key<x)ans+=now->ch[0]->size+1,now=now->ch[1];
 50             else now=now->ch[0];
 51         }
 52         return ans;
 53     }
 54     void rotate(Node *&x,int d){
 55         Node *y=x->ch[d];
 56         x->ch[d]=y->ch[d^1];
 57         y->ch[d^1]=x;
 58         x->pushup();y->pushup();
 59         x=y;
 60     }
 61     void insert(Node *&rt,int x){
 62         if(rt==null)rt=new Node(x);
 63         else{
 64             int d=x>rt->key;
 65             insert(rt->ch[d],x);
 66             if(rt->ch[d]->val<rt->val)rotate(rt,d);
 67         }
 68         rt->pushup();
 69     }
 70     void dfs(Node *rt){
 71         if(rt==null)return;
 72         dfs(rt->ch[0]);
 73         dfs(rt->ch[1]);
 74         delete rt;
 75     }
 76 }
 77 int head[N],e=1;
 78 struct edge{
 79     int v,next;
 80 }ed[N<<1];
 81 void add(int u,int v){
 82     ed[e].v=v;ed[e].next=head[u];
 83     head[u]=e++;
 84 }
 85 int dep[N],val[N],fa[N][20],r[N],w[N];
 86 int lca(int x,int y){
 87     if(dep[x]<dep[y])swap(x,y);
 88     for(int i=17;~i;i--)
 89         if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
 90     if(x==y)return x;
 91     for(int i=17;~i;i--)
 92         if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
 93     return fa[x][0];
 94 }
 95 int dis(int x,int y){
 96     return val[x]+val[y]-2*val[lca(x,y)];
 97 }
 98 int size[N],maxn[N],root,sum;
 99 bool vis[N];
100 int f[N],S[N];
101 void getroot(int x,int fa){
102     size[x]=1;maxn[x]=0;
103     for(int i=head[x];i;i=ed[i].next){
104         int v=ed[i].v;
105         if(v==fa||!vis[v])continue;
106         getroot(v,x);
107         size[x]+=size[v];
108         maxn[x]=max(maxn[x],size[v]);
109     }
110     maxn[x]=max(maxn[x],sum-size[x]);
111     if(maxn[x]<maxn[root])root=x;
112 }
113 void init(int x,int fa){
114     f[x]=fa;vis[x]=0;
115     int all=sum;
116     for(int i=head[x];i;i=ed[i].next){
117         int v=ed[i].v;
118         if(!vis[v])continue;
119         sum=size[v]<size[x]?size[v]:all-size[x];
120         root=0;
121         getroot(v,0);
122         init(root,x);
123     }
124 }
125 int T,tim[N];
126 void dfs1(int x,int fa,int s){
127     vis[x]=1;sum++;S[x]=0;tim[x]=T;
128     dfs(Treap::root[x]);Treap::root[x]=Treap::null;
129     dfs(Treap::root1[x]);Treap::root1[x]=Treap::null;
130     for(int i=head[x];i;i=ed[i].next){
131         int v=ed[i].v;
132         if(v==fa||S[v]>s)continue;
133         dfs1(v,x,s);
134     }
135 }
136 void dfs2(int x,int fa,int en){
137     int now=x;
138     while(now!=en){
139         S[now]++;
140         Treap::insert(Treap::root[now],dis(x,now)-r[x]);
141         if(f[now])Treap::insert(Treap::root1[now],dis(x,f[now])-r[x]);
142         now=f[now];
143     }
144     for(int i=head[x];i;i=ed[i].next){
145         int v=ed[i].v;
146         if(v==fa||tim[v]!=T)continue;
147         dfs2(v,x,en);
148     }
149 }
150 void rebuild(int x){
151     int fa=f[x];T++;sum=0;
152     dfs1(x,0,S[x]);root=0;
153     getroot(x,0);
154     init(root,fa);
155     dfs2(x,0,fa);
156 }
157 int query(int x){
158     int now=x;
159     int cnt=getrank(Treap::root[now],r[x]+1);
160     while(f[now]){
161         cnt+=Treap::getrank(Treap::root[f[now]],r[x]-dis(x,f[now])+1)
162             -Treap::getrank(Treap::root1[now],r[x]-dis(x,f[now])+1);
163         now=f[now];
164     }
165     return cnt-1;
166 }
167 void insert(int x){
168     if(x>1)add(x,f[x]),add(f[x],x);
169     fa[x][0]=f[x];
170     dep[x]=dep[fa[x][0]]+1;
171     val[x]=val[f[x]]+w[x];
172     for(int i=1;(1<<i)<=dep[x];i++)
173         fa[x][i]=fa[fa[x][i-1]][i-1];
174     S[x]++;
175     int now=x,ret=0;
176     while(f[now]){
177         Treap::insert(Treap::root[now],dis(x,now)-r[x]);
178         Treap::insert(Treap::root1[now],dis(x,f[now])-r[x]);
179         S[f[now]]++;
180         if(S[now]>S[f[now]]*0.88)ret=f[now];
181         now=f[now];
182     }Treap::insert(Treap::root[now],dis(x,now)-r[x]);
183     if(ret)rebuild(ret);
184     ans+=query(x);
185 }
186 int main(){
187     n=get();n=get();maxn[0]=N;
188     Treap::init();
189     for(int i=1;i<=n;i++){
190         f[i]=get();w[i]=get();r[i]=get();
191         f[i]=f[i]^(ans%1000000000);
192         insert(i);
193         printf("%lld\n",ans);
194     }
195     return 0;
196 }
View Code

 

posted @ 2018-01-12 17:31  Ren_Ivan  阅读(463)  评论(0编辑  收藏  举报