Andrew82 @ 2019-04-27 12:18:35
看提交记录里面很多人都是31分诶,肯定有一个坑!但是我不知道诶
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num); memset(arry,num,sizeof(arry));
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
#define asc(a) (a-'A')
#define ll long long
const int maxn=1e6+10,maxm=1e6+10;
int n,m,cnt=0;
struct node{
int e;int nxt;
}edge[maxn<<1];
int head[maxn];
int dep[maxn],son[maxn],siz[maxn],fa[maxn];
int seg[maxn],rev[maxn],top[maxn];
ll lazy[maxn<<2],sum[maxn<<2];
inline void addl(int u,int v){
edge[cnt].e=v;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
void dfs1(int u,int f){
dep[u]=dep[f]+1;
fa[u]=f;siz[u]=1;
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(v==f)continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v])son[u]=v;
}
}
void dfs2(int u,int fa){
if(son[u]){
seg[son[u]]=++seg[0];
rev[seg[0]]=son[u];
top[son[u]]=top[u];
dfs2(son[u],u);
}
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(!top[v]){
top[v]=v;
seg[v]=++seg[0];
rev[seg[0]]=v;
dfs2(v,u);
}
}
}
inline void buildtree(){clean(lazy,0);clean(sum,0);}
inline void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
inline void pushdown(int rt,int l,int r){
if(!lazy[rt])return;
int mid=(l+r)>>1;
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
sum[rt<<1]+=lazy[rt]*(mid-l+1);
sum[rt<<1|1]+=lazy[rt]*(r-(mid+1)+1);
lazy[rt]=0;
}
void update(int l,int r,int nl,int nr,int rt,int w){
if(l<=nl&&nr<=r){
lazy[rt]+=w;
sum[rt]+=w*(nr-nl+1);
return;
}
pushdown(rt,nl,nr);
int mid=((nr+nl)>>1);
if(mid>=l)update(l,r,nl,mid,rt<<1,w);
if(mid<r)update(l,r,mid+1,nr,rt<<1|1,w);
pushup(rt);
}
ll query(int l,int r,int nl,int nr,int rt){
if(l<=nl&&nr<=r)return sum[rt];
int mid=(nr+nl)>>1;
ll _sum=0;
if(mid>=l)_sum+=query(l,r,nl,mid,rt<<1);
if(mid<r)_sum+=query(l,r,mid+1,nr,rt<<1|1);
return _sum;
}
inline void updateline(int x,int y,int w){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy])swap(fx,fy),swap(x,y);
update(seg[fx],seg[x],1,seg[0],1,w);
x=fa[fx];fx=top[x];
}
if(dep[x]<dep[y])swap(x,y);
//update(seg[y],seg[x],1,seg[0],1,w);
update(seg[y]+1,seg[x],1,seg[0],1,w);
}
inline ll queryline(int x,int y){
int fx=top[x],fy=top[y];
ll _sum=0;
while(fx!=fy){
if(dep[fx]<dep[fy])swap(fx,fy),swap(x,y);
_sum+=query(seg[fx],seg[x],1,seg[0],1);
x=fa[fx],fx=top[x];
}
if(dep[x]<dep[y])swap(x,y);
//_sum+=query(seg[y],seg[x],1,seg[0],1);
_sum+=query(seg[y]+1,seg[x],1,seg[0],1);
return _sum;
}/*
inline ll queryline(int x,int y){
int _p=((dep[x]<dep[y])?y:x);
return query(seg[_p],seg[_p],1,seg[0],1);
}*/
inline void rep(){
register char op[100];
loop(i,1,m){
scanf("%s",op);
if(op[0]=='P'){
int xi,yi;
scanf("%d%d",&xi,&yi);
updateline(xi,yi,1);
}
else if(op[0]=='Q'){
int xi,yi;
scanf("%d%d",&xi,&yi);
printf("%lld\n",queryline(xi,yi));
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("datain.txt","r",stdin);
#endif // ONLINE_JUDGE
scanf("%d%d",&n,&m);
clean(head,-1);
loop(i,1,n){
int xi,yi;
scanf("%d%d",&xi,&yi);
addl(xi,yi),addl(yi,xi);
}
dfs1(1,0);
seg[1]=seg[0]=rev[1]=top[1]=1;
dfs2(1,0);
//#ifdef ONLtINE_JUDGE
//freopen("CON","r",stdin);
//m=INT_MAX;
//#endif // ONLINE_JUDGE
rep();
return 0;
}
by Alviss_lky @ 2019-04-27 12:38:58
祝您早日掉蓝(逃
by _WA自动机 @ 2019-04-27 12:39:09
%%%刚学OI就红名的大佬
by ferrum_cccp @ 2019-04-27 13:07:27
刚学oi就红名
by Zirnc @ 2019-04-27 13:16:08
去你的刚学OI
by StarLbright40 @ 2019-04-27 13:19:21
去你的红名蒟蒻
by hater @ 2019-04-27 13:55:37
去你的刚学OI
by 裘小小 @ 2019-04-27 14:07:31
去你的红名蒟蒻
by Andrew82 @ 2019-04-27 15:12:39
刚学蒟蒻就红名的oi表示31分的大多都是因为线段树打爆了,表现在:
在该pushup和pushdown时没有pushup和pushdown
左右移运算符打错
树链剖分时没有将点映射到线段树上
以及各种XX错误
by Andrew82 @ 2019-04-27 15:14:07
oi表示,除了红名,以上其他的修饰词都很贴切本蒟蒻,此贴完结
by 404_notfound @ 2019-08-21 12:04:04
Orz↑