膜网上题解。。。♂啊。然后看懂后写的很快。。。从早上调到中午。。。晚上回来继续。。。后重新打了一遍。。。似乎是因为ans在+的时候没有%mod的原因?应该是吧。便A了。。累垮。。。顽强的调试精神可嘉可贺啊~~~
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define adde(u,v) add(u,v),add(v,u)
#define qwq(x) for(edge *o=head[x];o;o=o->next)
#define op() clr(head,0);pt=edges;
#define lson l,m,x<<1
#define rson m+1,r,x<<1|1
const int nmax=50005;
const int inf=0x7f7f7f7f;
const int mod=201314;
int read(){
int x=0;char c=getchar();;
while(!isdigit(c)){
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
}
struct edge{
int to;edge *next;
};
edge edges[nmax<<2],*pt,*head[nmax];
int son[nmax],size[nmax],fa[nmax],dep[nmax],id[nmax],idx[nmax],tp[nmax],col[nmax<<2],sum[nmax<<2],n;
void add(int u,int v){
pt->to=v;pt->next=head[u];head[u]=pt++;
}
void dfs(int x){
size[x]=1;
qwq(x) if(o->to!=fa[x]){
int to=o->to;
dep[to]=dep[x]+1;fa[to]=x;
dfs(to);size[x]+=size[to];
if(!son[x]||size[to]>size[son[x]]) son[x]=to;
}
}
void DFS(int x,int top){
id[++id[0]]=x;idx[x]=id[0];tp[x]=top;
if(son[x]) DFS(son[x],top);
qwq(x) if(!idx[o->to]) DFS(o->to,o->to);
}
void pushdown(int x,int cnt){
if(col[x]){
col[x<<1]+=col[x];col[x<<1|1]+=col[x];
sum[x<<1]+=col[x]*(cnt-(cnt>>1));sum[x<<1|1]+=col[x]*(cnt>>1);
col[x]=0;
}
}
void update(int tl,int tr,int l,int r,int x){
if(tl<=l&&tr>=r){
col[x]+=1;sum[x]+=r-l+1;return ;
}
int m=(l+r)>>1;pushdown(x,r-l+1);
if(tl<=m) update(tl,tr,lson);
if(tr>m) update(tl,tr,rson);
sum[x]=sum[x<<1]+sum[x<<1|1];
}
void Update(int b){
while(tp[b]!=1) {
update(idx[tp[b]],idx[b],1,n,1);b=fa[tp[b]];
}
update(1,idx[b],1,n,1);
}
int query(int tl,int tr,int l,int r,int x){
if(tl<=l&&tr>=r) return sum[x];
int m=(l+r)>>1,ans=0;pushdown(x,r-l+1);
if(tl<=m) ans+=query(tl,tr,lson),ans%=mod;
if(tr>m) ans+=query(tl,tr,rson),ans%=mod;
return ans;
}
int qsum(int b){
int ans=0;
while(tp[b]!=1){
ans+=query(idx[tp[b]],idx[b],1,n,1);ans%=mod;b=fa[tp[b]];
}
ans+=query(1,idx[b],1,n,1);
return ans%mod;
}
struct node{
int num,to;bool f;
bool operator<(const node&rhs) const{
return to<rhs.to;}
};
node nodes[nmax<<1];
int q[nmax][3];
int main(){
op();clr(col,0);clr(sum,0);
n=read();int m=read(),u;
REP(i,2,n) u=read(),u++,adde(u,i);
clr(son,0);clr(idx,0);id[0]=0;dep[1]=0;
dfs(1);DFS(1,1);
int cur=0,tmp;
rep(i,m){
tmp=read(),nodes[++cur].to=tmp,nodes[cur].num=i,nodes[cur].f=true;
tmp=read(),tmp++,nodes[++cur].to=tmp,nodes[cur].num=i,nodes[cur].f=false;
tmp=read(),tmp++,q[i][0]=tmp;
}
sort(nodes+1,nodes+m+m+1);
cur=1;
rep(i,m+m){
while(cur<=nodes[i].to){
Update(cur),cur++;
//rep(j,20) printf("%d ",sum[j]);printf("
");
}
if(nodes[i].f) q[nodes[i].num][1]=qsum(q[nodes[i].num][0]);
else q[nodes[i].num][2]=qsum(q[nodes[i].num][0]);
}
rep(i,m) printf("%d
",(q[i][2]-q[i][1]+mod)%mod);
return 0;
}
3626: [LNOI2014]LCA
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1753 Solved: 668
[Submit][Status][Discuss]
Description
给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。
设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。
有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LCA(i,z)]。
(即,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和)
Input
第一行2个整数n q。
接下来n-1行,分别表示点1到点n-1的父节点编号。
接下来q行,每行3个整数l r z。
Output
输出q行,每行表示一个询问的答案。每个答案对201314取模输出
Sample Input
5 2
0
0
1
1
1 4 3
1 4 2
0
0
1
1
1 4 3
1 4 2
Sample Output
8
5
5
HINT
共5组数据,n与q的规模分别为10000,20000,30000,40000,50000。