並不對勁的bzoj3626:loj2558:p4211:[LNOI2014]LCA
阿新 • • 發佈:2019-02-23
ons clas [1] using long mem void sizeof space
題目大意
有一棵有\(n\)(\(n\leq5*10^4\))個點的樹,\(q\)(\(q\leq5*10^4\))次詢問,每次給出\(l,r,x\)表示詢問所有編號在\([l,r]\)的點與點\(x\)的LCA的深度之和
題解
將\([l,r]\)裏每個點和該點的所有祖先點權+1後,查詢點\(x\)和它的祖先的點權和就行了
可持久化線段樹維護
代碼
#include<algorithm> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<iomanip> #include<iostream> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define rep(i,x,y) for(register int i=(x);i<=(y);++i) #define dwn(i,x,y) for(register int i=(x);i>=(y);--i) #define view(u,k) for(int k=fir[u];k!=-1;k=nxt[k]) #define maxn 50010 #define ls (son[u][0]) #define rs (son[u][1]) #define lsa son[ua][0] #define rsa son[ua][1] #define lsb son[ub][0] #define rsb son[ub][1] #define mi (l+r>>1) #define LL long long using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)&&ch!=‘-‘)ch=getchar(); if(ch==‘-‘)f=-1,ch=getchar(); while(isdigit(ch))x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar(); return x*f; } void write(int x) { if(x==0){putchar(‘0‘),putchar(‘\n‘);return;} int f=0;char ch[20]; if(x<0)putchar(‘-‘),x=-x; while(x)ch[++f]=x%10+‘0‘,x/=10; while(f)putchar(ch[f--]); putchar(‘\n‘); return; } const int mod=201314; int n,q,rt[maxn],tr[maxn<<7],mk[maxn<<7],son[maxn<<7][2],ver[maxn<<7],fir[maxn],nxt[maxn],v[maxn],cnt,fa[maxn]; int dfn[maxn],tim,wson[maxn],siz[maxn],top[maxn],cntnd; void ade(int u1,int v1){v[cnt]=v1,nxt[cnt]=fir[u1],fir[u1]=cnt++;} void getsiz(int u) { siz[u]=1; view(u,k)if(v[k]!=fa[u]) { getsiz(v[k]),siz[u]+=siz[v[k]]; if(siz[v[k]]>siz[wson[u]])wson[u]=v[k]; } } void gettop(int u,int anc) { top[u]=anc,dfn[u]=++tim; if(wson[u])gettop(wson[u],anc); view(u,k)if(v[k]!=fa[u]&&v[k]!=wson[u])gettop(v[k],v[k]); } int mo(int x){if(x>=mod)return x-mod;if(x<0)return x+mod;return x;} int build(int l,int r) { int u=++cntnd; if(l==r){return u;} ls=build(l,mi),rs=build(mi+1,r); return u; } int add(int u,int l,int r,int x,int y,int vers) { int nu=vers==ver[u]?u:++cntnd; if(x<=l&&r<=y){son[nu][0]=ls,son[nu][1]=rs,ver[nu]=vers,tr[nu]=mo(tr[u]+r-l+1),mk[nu]=mo(mk[u]+1);return nu;} ver[nu]=vers,tr[nu]=mo(tr[u]+y-x+1),mk[nu]=mk[u]; if(x<=mi)son[nu][0]=add(ls,l,mi,x,min(mi,y),vers); else son[nu][0]=ls; if(y>mi)son[nu][1]=add(rs,mi+1,r,max(x,mi+1),y,vers); else son[nu][1]=rs; return nu; } int ask(int ua,int ub,int l,int r,int x,int y,int ad) { if(x<=l&&r<=y){return mo(mo(tr[ua]-tr[ub])+(LL)ad*(LL)(y-x+1)%mod);} int lans=0,rans=0; if(x<=mi)lans=ask(lsa,lsb,l,mi,x,min(mi,y),mo(ad+mo(mk[ua]-mk[ub]))); if(y>mi)rans=ask(rsa,rsb,mi+1,r,max(x,mi+1),y,mo(ad+mo(mk[ua]-mk[ub]))); return mo(lans+rans); } int main() { memset(fir,-1,sizeof(fir)); n=read(),q=read(); rep(i,2,n)fa[i]=read()+1,ade(fa[i],i); getsiz(1),gettop(1,1);rt[0]=build(1,n); rep(i,1,n) { rt[i]=rt[i-1];int x=i; while(top[x]!=1){rt[i]=add(rt[i],1,n,dfn[top[x]],dfn[x],i);x=fa[top[x]];} rt[i]=add(rt[i],1,n,1,dfn[x],i); } while(q--) { int l=read()+1,r=read()+1,x=read()+1,ans=0; while(top[x]!=1){ans=mo(ans+ask(rt[r],rt[l-1],1,n,dfn[top[x]],dfn[x],0));x=fa[top[x]];} ans=mo(ans+ask(rt[r],rt[l-1],1,n,1,dfn[x],0)); write(ans); } return 0; }
並不對勁的bzoj3626:loj2558:p4211:[LNOI2014]LCA