wc2014 紫荆花之恋
来源:互联网 发布:淘宝联盟点击数佣金 编辑:程序博客网 时间:2024/04/27 13:52
替罪羊树套treap,动态点分治维护
我去,分治树连接出向下的边没改。。。。调了我3个小时,真是醉飞了。。。。。
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>using namespace std;#define N 100010#define INF 1000000000const double Zy=0.85;int n,Root,tot,Sum,Now_root,Lim;long long Ans;struct Node{ int l,r,w,size,rnd; long long v;}t[N*150];struct Edge{ int to,next,value;}edge[N*2],edge1[N*2];int head[N],Tot,head1[N],Tot1;int size[N],root[N],S_root[N],f[N],A[N],fa[N][100],Floor[N];long long dis[N][100];bool done[N],QQQ;queue<int> Q,E;queue<int> qq;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} return x*f;}int New_edgenum() //First CK:Correct{ if(!E.empty()) { int now=E.front();E.pop(); return now; } else return ++Tot1;}void Addedge(int u,int v,int w) //First CK:Correct{ Tot++;edge[Tot].next=head[u];edge[Tot].to=v;edge[Tot].value=w;head[u]=Tot; Tot++;edge[Tot].next=head[v];edge[Tot].to=u;edge[Tot].value=w;head[v]=Tot;}void Addedge1(int u,int v) //First CK:Correct{ int now=New_edgenum(); edge1[now].next=head1[u];edge1[now].to=v;head1[u]=now;}void Rec_treap(int &k) //First CK:Correct{ if(!k)return; if(t[k].l)Rec_treap(t[k].l); if(t[k].r)Rec_treap(t[k].r); t[k].v=t[k].size=t[k].w=t[k].rnd=0; Q.push(k);k=0;}int New_node() //First CK:Correct{ if(!Q.empty()) { int now=Q.front();Q.pop(); return now; } else return ++tot;}void Pushup(int k) // First CK:Correct{ t[k].size=t[t[k].l].size+t[t[k].r].size+t[k].w;}void Left_rotate(int &k) //First CK:Correct{ int tmp=t[k].r;t[k].r=t[tmp].l;t[tmp].l=k; t[tmp].size=t[k].size;Pushup(k);k=tmp;}void Right_rotate(int &k) //First CK:Correct{ int tmp=t[k].l;t[k].l=t[tmp].r;t[tmp].r=k; t[tmp].size=t[k].size;Pushup(k);k=tmp;}void Insert(int &k,long long x) //First CK:Correct{ if(!k) { k=New_node();t[k].v=x;t[k].size=t[k].w=1; t[k].rnd=rand();return; } t[k].size++; if(t[k].v==x) t[k].w++; else if(t[k].v>x) { Insert(t[k].l,x); if(t[t[k].l].rnd<t[k].rnd)Right_rotate(k); } else { Insert(t[k].r,x); if(t[t[k].r].rnd<t[k].rnd)Left_rotate(k); }}int Query(int k,long long x) //First CK:Correct{ if(!k) return 0; if(t[k].v==x) { return t[t[k].l].size+t[k].w; } else if(t[k].v>x) return Query(t[k].l,x); else return Query(t[k].r,x)+t[t[k].l].size+t[k].w;}void Find_root(int k,int last) //First CK:Correct{ size[k]=1;f[k]=0; for(int i=head[k];i;i=edge[i].next) { int v=edge[i].to; if(done[v]||v==last) continue; Find_root(v,k); size[k]+=size[v]; f[k]=max(f[k],size[v]); } f[k]=max(f[k],Sum-f[k]); if(f[k]<f[Now_root]) Now_root=k;}void DFS(int k,int Fa,int rt,int floor){ Insert(root[rt],dis[k][floor]-A[k]);size[k]=1; for(int i=head[k];i;i=edge[i].next) { int v=edge[i].to; if(v==Fa||done[v]) continue; dis[v][floor]=dis[k][floor]+edge[i].value; fa[v][floor]=rt; DFS(v,k,rt,floor); size[k]+=size[v]; }}void Get_contribution(int k,int rt){ Insert(S_root[rt],dis[k][Floor[rt]-1]-A[k]); for(int i=head1[k];i;i=edge1[i].next) { int v=edge1[i].to; Get_contribution(v,rt); }}void Work(int k,int floor){ done[k]=true;Floor[k]=floor; fa[k][floor]=k;dis[k][floor]=0; DFS(k,0,k,floor); for(int i=head[k];i;i=edge[i].next) { int v=edge[i].to; if(done[v]||!v) continue; Sum=size[v];Now_root=0; Find_root(v,Now_root); Addedge1(k,Now_root); Work(Now_root,floor+1); } Get_contribution(k,k);}bool Balance(int k){ int Max=0; for(int i=head1[k];i;i=edge1[i].next) { int v=edge1[i].to; Max=max(Max,size[v]); } return Zy*size[k]>=Max;}void Rec(int k){ Rec_treap(root[k]);Rec_treap(S_root[k]); for(int i=head1[k];i;i=edge1[i].next) { int v=edge1[i].to; Rec(v); E.push(i); } head1[k]=0;done[k]=0;}void Rebuild(int k){ int FFF=fa[k][Floor[k]-1]; for(int j=head1[FFF];j;j=edge1[j].next) { int v=edge1[j].to; qq.push(v); E.push(j); } head1[FFF]=0; while(!qq.empty()) { int now=qq.front();qq.pop(); if(now!=k) Addedge1(FFF,now); } Rec(k); Now_root=0;Sum=size[k]; Find_root(k,Now_root); Addedge1(FFF,Now_root); Work(Now_root,Floor[k]);}void My_insert(int Fa,int k,int value){ int Now_floor=Floor[Fa];Floor[k]=Now_floor+1; fa[k][Floor[k]]=k;dis[k][Floor[k]]=0; if(Fa!=0) {Addedge(Fa,k,value);Addedge1(Fa,k);} for(int i=Floor[k];i>=1;i--) { int pos;long long d; if(i==Floor[k]) pos=k,d=0; else pos=fa[Fa][i],d=value+dis[Fa][i]; fa[k][i]=pos;dis[k][i]=d; size[pos]++; Insert(root[pos],d-A[k]); if(i>1) { Ans+=Query(root[fa[Fa][i-1]],(long long)A[k]-value-dis[Fa][i-1]); Ans-=Query(S_root[pos],(long long)A[k]-value-dis[Fa][i-1]); Insert(S_root[pos],(long long)value+dis[Fa][i-1]-A[k]); } } int sheep=0; for(int i=Floor[k];i>=1;i--) { int now=fa[k][i]; if(!Balance(now))sheep=now; } if(sheep)Rebuild(sheep);}int main(){ int hehe=read(); n=read();f[0]=INF; for(int i=1;i<=n;i++) done[i]=true; for(int i=1;i<=n;i++) { int x=read(),y=read();A[i]=read(); x^=(Ans%1000000000); My_insert(x,i,y); printf("%lld\n",Ans); } return 0;}
0 0
- wc2014 紫荆花之恋
- 【WC2014】紫荆花之恋
- [BZOJ3435/UOJ55/WC2014]紫荆花之恋
- BZOJ3435: [Wc2014]紫荆花之恋 动态树分治 替罪羊树
- [替罪羊树 动态点分治 替罪羊式重构] BZOJ 3435 [Wc2014]紫荆花之恋 & UOJ #55 【WC2014】紫荆花之恋
- BZOJ 3435 Wc2014 紫荆花之恋 动态树分治+替罪羊树+Treap
- 紫荆花之恋
- bzoj 3435 紫荆花之恋 动态树分治+替罪羊+treap
- BZOJ3434: [Wc2014]时空穿梭
- 【bzoj 3434】 WC2014 时空穿梭 - 乱搞数学题
- BZOJ 3434 Wc2014 时空穿梭 莫比乌斯反演
- 雪,之韵,之恋,之......
- 待字闺中之单链表和之恋
- 凤凰城之恋
- “枫”之恋
- 广岛之恋
- 《红色之恋》
- 布拉格之恋
- Android 四大组件之BroadcastReceiver
- CentOS笔记——配置DNS服务器
- android graphic(2)—EGL和OpenGL ES
- Android源码学习之一-Activity是如何实现主题变化的
- RHEL 6.2配置本地yum源
- wc2014 紫荆花之恋
- 批处理管理文件以及文件夹
- HDU 1074 Doing Homework (状压dp)
- Android学习笔记-使用layout方法使View随手指的滑动而滑动
- 查询sql server 2008所有表和行数
- 安装pip ---python windows
- 如何将两个有重复字符在内的字符串合并成一个,并且排序
- imagenet原图片下载地址
- 安卓开发中高级组件之选项卡的应用