https://www.luogu.org/problemnew/show/P4211
人生中第一道黑题!!!我觉得差不多紫题难度吧qaq
题意:
思路:
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; inline int read(){ int x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+ch-48; ch=getchar(); } return x; } const int maxn=5e4+4; int head[maxn],siz[maxn],fa[maxn],son[maxn],top[maxn],seg[maxn],rev[maxn],dep[maxn]; int n,m,cnt=0; struct node{ int to,next; }e[maxn]; inline void add(int u,int v){ e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt++; } inline void dfs1(int u,int f){ siz[u]=1; fa[u]=f; dep[u]=dep[f]+1; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(v==f) continue; dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } inline void dfs2(int u,int t){ top[u]=t;seg[u]=++seg[0];rev[seg[0]]=u; if(!son[u]) return; dfs2(son[u],t); for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(!top[v]) dfs2(v,v); } } struct xds{ int l,r,tag,val; }tr[maxn<<2]; int a[maxn],b[maxn]; inline void build(int k,int l,int r){ tr[k].l=l,tr[k].r=r; if(l==r) return; int mid=l+r>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); } vector<pair<int,int> >ve[maxn]; inline void pushdown(int k){ tr[k<<1].val=(tr[k<<1].val+tr[k].tag*(tr[k<<1].r-tr[k<<1].l+1))%201314; tr[k<<1|1].val=(tr[k<<1|1].val+tr[k].tag*(tr[k<<1|1].r-tr[k<<1|1].l+1))%201314; tr[k<<1].tag+=tr[k].tag; tr[k<<1|1].tag+=tr[k].tag; tr[k].tag=0; } inline void update(int k,int x,int y){ int l=tr[k].l,r=tr[k].r; if(l==x&&y==r){ tr[k].val=(tr[k].val+r-l+1)%201314;tr[k].tag++; return; } pushdown(k); tr[k].val=(tr[k].val+y-x+1); int mid=l+r>>1; if(x>mid) update(k<<1|1,x,y); else if(y<=mid) update(k<<1,x,y); else {update(k<<1,x,mid);update(k<<1|1,mid+1,y);} tr[k].val=(tr[k<<1].val+tr[k<<1|1].val)%201314; } inline int query(int k,int x,int y){ int l=tr[k].l,r=tr[k].r; if(l==x&&y==r){ return tr[k].val; } pushdown(k); int mid=l+r>>1; int sum=0; if(x>mid) sum=query(k<<1|1,x,y); else if(y<=mid) sum=query(k<<1,x,y); else sum=query(k<<1,x,mid)+query(k<<1|1,mid+1,y); tr[k].val=(tr[k<<1].val+tr[k<<1|1].val)%201314; return sum; } inline void change(int x,int y){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); update(1,seg[top[x]],seg[x]); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); update(1,seg[x],seg[y]); } inline int chaxun(int x,int y){ int sum=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); sum=(sum+query(1,seg[top[x]],seg[x]))%201314; x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); sum=(sum+query(1,seg[x],seg[y]))%201314; return sum; } int main(){ n=read();int q=read(); memset(head,-1,sizeof(head)); memset(a,-1,sizeof(a)); for(int i=1;i<n;i++){ int x=read(); add(x+1,i+1); } dfs1(1,0); dfs2(1,1); build(1,1,n); for(int i=1;i<=q;i++){ int x=read(),y=read(),z=read(); x++,y++,z++; ve[x-1].push_back(make_pair(i,z)); ve[y].push_back(make_pair(i,z)); } for(int j=0;j<ve[0].size();j++) a[ve[0][j].first]=0; for(int i=1;i<=n;i++){ change(1,i); for(int j=0;j<ve[i].size();j++){ if(a[ve[i][j].first]==-1) a[ve[i][j].first]=chaxun(1,ve[i][j].second); else b[ve[i][j].first]=chaxun(1,ve[i][j].second); } } for(int i=1;i<=q;i++) printf("%d ",(b[i]-a[i]+201314)%201314); }