BZOJ3589: 动态树
来源:互联网 发布:手机天网视频软件 编辑:程序博客网 时间:2024/05/24 07:25
树链剖分。。
沃日打错树剖+路径并
感觉要滚粗啊
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>using namespace std;#define ll long longconst ll Mod=1ll<<31;char c;inline void read(ll &a){ a=0;do c=getchar();while(c<'0'||c>'9'); while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}struct Chain{ Chain *next; ll u;}*Head[300001];#define ll long longll Dep[300001];namespace LC{ll Len[600001];ll ST[1000001][20];ll In[600001];ll Block[600001];ll tot;inline ll L(ll x,ll y){return Dep[x]<Dep[y]?x:y;}inline ll LCA(ll a,ll b){ if(!(a^b))return a; ll x=In[a],y=In[b]; if(x>y)swap(x,y); ll Len=y-x+1,Bl=Block[Len]; return L(ST[x][Bl],ST[y-(1<<Bl)+1][Bl]);}ll Dis(ll u,ll v){return Len[u]+Len[v]-2*Len[LCA(u,v)];}inline void Bg(){ Len[0]=1ll<<29; Dep[0]=1ll<<29; ll base; for(ll i=1,base=1;i<=19;i++,base<<=1) for(ll j=1;j<=tot;j++) ST[j][i]=L(ST[j][i-1],ST[j+base][i-1]); ll con=0; for(ll i=1;i<=tot;i++) if(i^(i&-i))Block[i]=con-1; else Block[i]=con++;}void DFS(ll u,ll fa,ll dep){ Dep[u]=dep; ST[In[u]=++tot][0]=u; for(Chain*tp=Head[u];tp;tp=tp->next) if(tp->u^fa) { DFS(tp->u,u,dep+1); ST[++tot][0]=u; } if(u^fa)return ; Bg();}}ll t;namespace Seg{ struct N { ll l,r; ll sum,flag; }T[600001]; inline void Build(ll place,ll l,ll r) { ll Mid=l+r>>1,lc=place<<1,rc=lc|1; T[place].l=l,T[place].r=r; if(l^r) Build(lc,l,Mid),Build(rc,Mid+1,r); } inline void AddFlag(ll place,ll Delta) { T[place].flag+=Delta,T[place].sum+=Delta*(T[place].r-T[place].l+1); T[place].flag%=Mod,T[place].sum%=Mod; } inline void pushdown(ll place) { ll lc=place<<1,rc=lc|1; T[lc].flag+=T[place].flag,T[rc].flag+=T[place].flag; T[lc].sum+=T[place].flag*(T[lc].r-T[lc].l+1), T[rc].sum+=T[place].flag*(T[rc].r-T[rc].l+1); T[lc].flag%=Mod;T[rc].flag%=Mod; T[lc].sum%=Mod;T[rc].sum%=Mod; T[place].flag=0; } void Add(ll place,ll l,ll r,ll Delta) { if(T[place].l>=l&&T[place].r<=r) { AddFlag(place,Delta);return;}// if(T[place].flag)pushdown(place); ll lc=place<<1,rc=lc|1,Mid=T[lc].r; if(Mid<r)Add(rc,l,r,Delta); if(Mid>=l)Add(lc,l,r,Delta); T[place].sum=(T[lc].sum+T[rc].sum+T[place].flag*(T[place].r-T[place].l+1))%Mod; } ll Query(ll place,ll l,ll r) { if(T[place].l>=l&&T[place].r<=r)return T[place].sum;// if(T[place].flag)pushdown(place); ll res=T[place].flag*(min(r,T[place].r)-max(l,T[place].l)+1),lc=place<<1,rc=lc|1,Mid=T[lc].r; if(l<=Mid)res+=Query(lc,l,r); if(r>Mid)res+=Query(rc,l,r); res%=Mod; return res; }}struct Path{ll f,s;};Path operator &(Path a,Path b){ Path res; res.f=LC::LCA(a.f,b.f); if(res.f==b.f)res.f=a.f; else if(res.f==a.f)res.f=b.f; else return (Path){-1,-1}; res.s=LC::LCA(a.s,b.s); if(Dep[res.f]>Dep[res.s])return (Path){-1,-1}; return res;}ll K;Path X[30001];ll HeavySon[300001],Size[300001],F[300001];void DFS(ll u,ll f){ Size[u]++; F[u]=f; for(Chain *tp=Head[u];tp;tp=tp->next) if(tp->u!=f) { DFS(tp->u,u); Size[u]+=Size[tp->u]; if(Size[tp->u]>Size[HeavySon[u]])HeavySon[u]=tp->u; }}ll tot,CBG[300001],CED[300001],CPL[300001],CND[300001];void DFS2(ll u,ll f,ll BG){ CBG[u]=BG; CND[CPL[u]=++tot]=u; if(HeavySon[u]) DFS2(HeavySon[u],u,BG); for(Chain *tp=Head[u];tp;tp=tp->next) if(tp->u!=HeavySon[u]&&tp->u!=f) DFS2(tp->u,u,tot+1); CED[u]=tot;}ll Query(Path X){ ll res=0,u=X.f,v=X.s; while(CBG[v]!=CBG[u]) { res+=Seg::Query(1,CBG[v],CPL[v]); v=F[CND[CBG[v]]]; } res+=Seg::Query(1,CPL[u],CPL[v]); return res;}ll Add(ll u,ll Delta){ Seg::Add(1,CPL[u],CED[u],Delta);}ll Div(ll x,Path Tp){ if(x==K+1)return 0; if(Tp.f==4&&Tp.s==4) x++,x--; if(Tp.f==-1)return 0; ll res=Query(Tp); for(ll i=x+1;i<=K;i++) res-=Div(i,Tp&X[i]),res%=Mod; return res%Mod;}inline void ADD(ll a,ll b){ Chain *tp=new Chain; tp->u=b,tp->next=Head[a],Head[a]=tp;} ll n,Q ;int main(){ read(n); ll i,j,k,l; for(i=1;i<n;i++) { read(j),read(k),ADD(j,k),ADD(k,j); } LC::DFS(1,1,1); DFS(1,1); DFS2(1,1,1); Seg::Build(1,1,tot); read(Q); while(Q--) { ll op; read(op); if(op) { read(K); ll ans=0,j,k; for(i=1;i<=K;i++) { read(j),read(k); X[i].f=Dep[j]<Dep[k]?j:k; X[i].s=j+k-X[i].f; } for(i=1;i<=K;i++) ans+=Div(i,X[i]); printf("%lld\n",(ans%Mod+Mod)%Mod); } else read(j),read(k),Add(j,k); }// printf("%d\n",t); return 0;}
0 0
- bzoj3589 动态树
- BZOJ3589: 动态树
- 树链剖分 BZOJ3589 动态树
- 【bzoj3589】动态树 树链剖分+线段树
- BZOJ3589动态树,BIT+容斥
- [BZOJ3589]动态树(树链剖分+dfs序+lca)
- Bzoj3589:动态树:树链剖分+容斥原理+树链的并
- 动态树
- 动态树
- 动态树
- 动态树
- 动态树
- 动态规划----树型动态规划
- 动态加载树----treeView
- 动态加载树
- Javascript动态目录树
- Delphi动态创建树
- 动态加载树TreeView
- parseSdkContent failed Could not initialize class android.graphics
- 表格组件列属性formatter和styler使用方法
- 网易实习招聘,求一个字符串的所有子回文字符串
- leetcode——290——Word Pattern
- OSI七层模型的每一层都有哪些协议
- BZOJ3589: 动态树
- Java初学者需掌握的30个基本概念
- 【HDU3466】Proud Merchants(01背包)
- Problem-1017
- Better History(历史记录)
- [R语言] quantmod 包获取国内的股票数据
- GNU开发笔记--开发环境基础(持续更新)
- Jsp
- java:double四舍五入并保留两位小数的方法