bzoj3626: [LNOI2014]LCA

膜网上题解。。。♂啊。然后看懂后写的很快。。。从早上调到中午。。。晚上回来继续。。。后重新打了一遍。。。似乎是因为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 MB
Submit: 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

Sample Output

8
5

HINT

共5组数据,n与q的规模分别为10000,20000,30000,40000,50000。


Source

[Submit][Status][Discuss]
原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5668127.html