GLZP @ 2019-07-14 20:09:02
rt
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<cmath>
#define ll long long
using namespace std;int k=0;
struct node{
int l,r,w;
int lazy;
}tr[200010*4];
int n,m;
int head[400010],next[400010],to[400010];
void add(int u,int v)
{
to[++k]=v;
next[k]=head[u];
head[u]=k;
}
int fa[400010],dep[400010],size[400010],son[400010];
void down(int id)
{
tr[id<<1].lazy+=tr[id].lazy;
tr[id<<1|1].lazy+=tr[id].lazy;
tr[id].lazy=0;
}
void dfs1(int u,int f)
{
size[u]=1;
fa[u]=f;
for(int i=head[u];i;i=next[i])
{
int v=to[i];
if(fa[u]==v)continue;
dep[v]=dep[u]+1;
dfs1(v,u);
size[u]+=size[v];
if(!son[u]||size[v]>size[son[u]])size[u]=v;
}
}
int tid[400010],tim,pos[400010],top[400010];
void dfs2(int u,int tp)
{
tid[u]=++tim;
pos[tim]=tim;
top[u]=tp;
if(son[u])dfs2(son[u],tp);
for(int i=head[u];i;i=next[i])
{
int v=to[i];
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void build(int id,int l,int r)
{
tr[id].l=l;tr[id].r=r;
if(l==r)
{
return ;
}
int mid=(l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
}
void cha(int id,int l,int r,int val)
{
if(tr[id].r<l||tr[id].l>r)return;
if(tr[id].l>=l&&tr[id].r<=r)
{
tr[id].lazy+=val;
return ;
}
if(tr[id].lazy)down(id);
cha(id<<1,l,r,val);
cha(id<<1|1,l,r,val);
}
void change(int a,int b,int val)
{
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]])swap(a,b);
cha(1,tid[top[a]],tid[a],val);
a=fa[top[a]];
}
if(dep[a]>dep[b])swap(a,b);
cha(1,tid[a]+1,tid[b],1);
}
int que(int id,int l,int r)
{
if(tr[id].r<l||tr[id].l>r)return 0;
if(tr[id].l>=l&&tr[id].r<=r)
{
return tr[id].lazy;
}
return que(id<<1,l,r)+que(id<<1|1,l,r);
}
void ask(int a,int b)
{
int ans=0;
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]])swap(a,b);
ans+=que(1,tid[top[a]],tid[a]);
a=fa[top[a]];
}
if(dep[a]>dep[b])swap(a,b);
ans+=que(1,tid[a]+1,tid[b]);
printf("%d\n",ans);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,tim);
for(int i=1;i<=m;i++)
{
char opt;
scanf(" %c",&opt);
if(opt=='P')
{
int x,y;
scanf("%d%d",&x,&y);
change(x,y,1);
}
else
{
int x,y;
scanf("%d%d",&x,&y);
ask(x,y);
}
}
return 0;
}
by zrzluck99 @ 2019-07-14 20:14:08
@树链剖分