【CODEVS】树链剖分板子

来源:互联网 发布:国家统计局gdp数据 编辑:程序博客网 时间:2024/05/01 04:39

由于线段树拖了很久,所以链剖也拖了很久

史上第一道链剖,特此纪念

【羞耻,调了好久结果又是线段树萎了】

【其实题中不需要lazy,但有备无患!!!】

#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define mid ((L[id]+R[id])>>1)#define ls (id<<1)#define rs (id<<1|1)#define size(o) (R[o]-L[o]+1)using namespace std;const int maxn=100001,maxm=maxn<<1,maxd=maxn<<2|1;int fir[maxn],nxt[maxm],dis[maxm],n,q;int son[maxn],fa[maxn],heavy[maxn],top[maxn],dfn[maxn],deep[maxn],INDEX;int tree[maxd],lazy[maxd],L[maxd],R[maxd];inline int gi() {int f=1,p=0;char c=getchar();while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar();return p*f;}inline void adde(int a,int b,int id) {nxt[id]=fir[a],fir[a]=id,dis[id]=b;}void init();void work();int main() {init();q=gi();while(q--)work();return 0;}void dfs1(int now,int D) {son[now]=1,deep[now]=D;int maxx=0;for(int i=fir[now]; i; i=nxt[i])if(!son[dis[i]]) {fa[dis[i]]=now,dfs1(dis[i],D+1),son[now]+=son[dis[i]];if(son[dis[i]]>maxx)heavy[now]=dis[i],maxx=son[dis[i]];}}void dfs2(int now,int tp) {top[now]=tp,dfn[now]=++INDEX;if(heavy[now])dfs2(heavy[now],tp);for(int i=fir[now]; i; i=nxt[i])if(!dfn[dis[i]])dfs2(dis[i],dis[i]);}void build(int id,int l,int r) {L[id]=l,R[id]=r;if(l^r)build(ls,l,mid),build(rs,mid+1,r);}void init() {n=gi();int a,b;for(int i=1; i<n; i++)a=gi(),b=gi(),adde(a,b,(i<<1)-1),adde(b,a,i<<1);dfs1(1,0),dfs2(1,1),build(1,1,n);}int l,r;void doit(int id) {tree[ls]+=lazy[id]*size(ls),lazy[ls]+=lazy[id];tree[rs]+=lazy[id]*size(rs),lazy[rs]+=lazy[id];lazy[id]=0;}void segup(int id) {if(L[id]!=R[id])doit(id);if(L[id]>=l&&R[id]<=r) {tree[id]+=size(id),lazy[id]++;return;}if(l<=mid)segup(ls);if(r>mid)segup(rs);tree[id]=tree[ls]+tree[rs];}int segsum(int id) {if(L[id]!=R[id])doit(id);if(L[id]>=l&&R[id]<=r)return tree[id];if(l<=mid)if(r>mid)return segsum(ls)+segsum(rs);else return segsum(ls);else return segsum(rs);}void update(int a,int b) {while(top[a]^top[b]) {if(deep[top[a]]>deep[top[b]])l=dfn[top[a]],r=dfn[a],segup(1),a=fa[top[a]];else l=dfn[top[b]],r=dfn[b],segup(1),b=fa[top[b]];}l=min(dfn[a],dfn[b]),r=max(dfn[a],dfn[b]);segup(1);}int query(int a,int b) {int ans=0;while(top[a]^top[b]) {if(deep[top[a]]>deep[top[b]])l=dfn[top[a]],r=dfn[a],ans+=segsum(1),a=fa[top[a]];else l=dfn[top[b]],r=dfn[b],ans+=segsum(1),b=fa[top[b]];}l=min(dfn[a],dfn[b]),r=max(dfn[a],dfn[b]);return ans+segsum(1);}void work() {int a=gi(),b=gi(),c=gi();if(a==1)update(b,c);else printf("%d\n",query(b,c));}


2 1
原创粉丝点击