Wc2014 紫荆花之恋
2017-01-22 10:52
429 查看
哈哈哈哈哈哈哈哈哈哈哈哈我终于过了!!!!!!!!!!!!!!!
从昨天上午就开始写了,下午回家之后调了一会儿没什么感觉,就删了重打了一遍,然后调了一晚上+今天半个上午......我*******终于过了......
一道极其恶心的动态树分治......
首先点分治,限制条件就变成了di+dj<=ri+rj,移项得rj-dj>=di-ri,对重心和子树开平衡树维护di-ri即可。
查询的时候先跳点分治树更新答案,然后逐层把di-ri插入平衡树,上跳的过程中判断是否有子树失衡(某个子树大于子树总大小的alpha倍),有则提出来暴力重构成完全平衡的点分治树。
各种坑爹细节和脑残错误调了一天,不过还是过了,激动......
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn=100010; const double alpha=0.7; struct node{ static int randint(){ static int a=1213,b=97818217,p=998244353,x=751815431; x=a*x+b;x%=p; return x<0?(x+=p):x; } int data,size,p; node *ch[2]; node(int d):data(d),size(1),p(randint()){} inline void refresh(){size=ch[0]->size+ch[1]->size+1;} }*null=new node(0),*root[maxn],*root1[maxn][50]; void addnode(int,int); void rebuild(int,int,int,int); void dfs_getcenter(int,int,int&); void dfs_getdis(int,int,int,int); void dfs_destroy(int,int); void insert(int,node*&); int order(int,node*); void destroy(node*&); void rot(node*&,int); vector<int>G[maxn],W[maxn]; int size[maxn]={0},siz[maxn][50]={0},son[maxn]; bool vis[maxn]; int depth[maxn],p[maxn],d[maxn][50],id[maxn][50]; int n,m,w[maxn],tmp; long long ans=0; int main(){ null->size=0; null->ch[0]=null->ch[1]=null; scanf("%*d%d",&n); fill(vis,vis+n+1,true); fill(root,root+n+1,null); for(int i=0;i<=n;i++)fill(root1[i],root1[i]+50,null); scanf("%*d%*d%d",&w[1]); insert(-w[1],root[1]); size[1]=1; printf("0\n"); for(int i=2;i<=n;i++){ scanf("%d%d%d",&p[i],&tmp,&w[i]); p[i]^=(ans%(int)1e9); G[i].push_back(p[i]); W[i].push_back(tmp); G[p[i]].push_back(i); W[p[i]].push_back(tmp); addnode(i,tmp); printf("%lld\n",ans); } return 0; } void addnode(int x,int z){//wj-dj>=di-wi depth[x]=depth[p[x]]+1; size[x]=1; insert(-w[x],root[x]); int rt=0; for(int u=p[x],k=depth[p[x]];u;u=p[u],k--){ if(u==p[x]){ id[x][k]=x; d[x][k]=z; } else{ id[x][k]=id[p[x]][k]; d[x][k]=d[p[x]][k]+z; } ans+=order(w[x]-d[x][k],root[u])-order(w[x]-d[x][k],root1[id[x][k]][k]); insert(d[x][k]-w[x],root[u]); insert(d[x][k]-w[x],root1[id[x][k]][k]); size[u]++; siz[id[x][k]][k]++; if(siz[id[x][k]][k]>size[u]*alpha+5)rt=u; } id[x][depth[x]]=0; d[x][depth[x]]=0; if(rt){ dfs_destroy(rt,depth[rt]); rebuild(rt,depth[rt],size[rt],p[rt]); } } void rebuild(int x,int k,int s,int pr){ int u=0; dfs_getcenter(x,s,u); vis[x=u]=true; p[x]=pr; depth[x]=k; size[x]=s; d[x][k]=id[x][k]=0; destroy(root[x]); insert(-w[x],root[x]); if(s<=1)return; for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]){ p[G[x][i]]=0; d[G[x][i]][k]=W[x][i]; siz[G[x][i]][k]=p[G[x][i]]=0; destroy(root1[G[x][i]][k]); dfs_getdis(G[x][i],x,G[x][i],k); } 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); } void dfs_getcenter(int x,int s,int &u){ size[x]=1; son[x]=0; for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]&&G[x][i]!=p[x]){ p[G[x][i]]=x; dfs_getcenter(G[x][i],s,u); size[x]+=size[G[x][i]]; if(size[G[x][i]]>size[son[x]])son[x]=G[x][i]; } if(!u||max(s-size[x],size[son[x]])<max(s-size[u],size[son[u]]))u=x; } void dfs_getdis(int x,int u,int rt,int k){ insert(d[x][k]-w[x],root[u]); insert(d[x][k]-w[x],root1[rt][k]); id[x][k]=rt; siz[rt][k]++; size[x]=1; for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]&&G[x][i]!=p[x]){ p[G[x][i]]=x; d[G[x][i]][k]=d[x][k]+W[x][i]; dfs_getdis(G[x][i],u,rt,k); size[x]+=size[G[x][i]]; } } void dfs_destroy(int x,int k){ vis[x]=false; for(int i=0;i<(int)G[x].size();i++)if(depth[G[x][i]]>=k&&G[x][i]!=p[x]){ p[G[x][i]]=x; dfs_destroy(G[x][i],k); } } void insert(int x,node *&rt){ if(rt==null){ rt=new node(x); rt->ch[0]=rt->ch[1]=null; return; } int d=x>=rt->data; insert(x,rt->ch[d]); rt->refresh(); if(rt->ch[d]->p<rt->p)rot(rt,d^1); } int order(int x,node *rt){ int ans=0,d; x++; while(rt!=null){ if((d=x>rt->data))ans+=rt->ch[0]->size+1; rt=rt->ch[d]; } return ans; } void destroy(node *&x){ if(x==null)return; destroy(x->ch[0]); destroy(x->ch[1]); delete x; x=null; } void rot(node *&x,int d){ node *y=x->ch[d^1]; x->ch[d^1]=y->ch[d]; y->ch[d]=x; x->refresh(); (x=y)->refresh(); } /* Wc2014 紫荆花之恋 di+dj<=wi+wj,移项得wj-dj>=di-wi,动态点分治维护即可。 每个重心和子树存一棵平衡树维护di-wi,加点的时候跳点分治树更新答案后加入新点, 加入之后判断子树是否失衡,找出最高的失衡节点,把整个子树暴力重构成完全平衡的点分治树。 */View Code
相关文章推荐
- [WC 2014]紫荆花之恋
- BZOJ3435 & 洛谷3920 & UOJ55:[WC2014]紫荆花之恋
- 数据结构(平衡树,树分治,暴力重构):WC 2014 紫荆花之恋
- 【BZOJ3435】【UOJ55】【WC2014】紫荆花之恋
- uoj#55./bzoj3435 【WC2014】紫荆花之恋 //替罪羊式重构点分树
- [WC2014]紫荆花之恋
- bzoj3435 [Wc2014]紫荆花之恋
- bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 && AC400
- 【BZOJ3435】[Wc2014]紫荆花之恋 替罪点分树+SBT
- BZOJ 3435: [Wc2014]紫荆花之恋
- BZOJ 3435 Wc2014 紫荆花之恋 动态树分治+替罪羊树+Treap
- [BZOJ3435][Wc2014]紫荆花之恋-替罪羊树-treap-动态点分治
- wc2014 紫荆花之恋
- UOJ#55 [WC2014]紫荆花之恋
- 【WC2014】紫荆花之恋
- NKOJ 2703 (WC 2014)紫荆花之恋 (点分治+平衡树+替罪羊)
- Wc2014 紫荆花之恋
- bzoj3435 [Wc2014]紫荆花之恋
- bzoj3435 [Wc2014]紫荆花之恋(动态点分治+替罪羊树)
- [替罪羊树 动态点分治 替罪羊式重构] BZOJ 3435 [Wc2014]紫荆花之恋 & UOJ #55 【WC2014】紫荆花之恋