fighter_OI @ 2017-10-11 00:19:55
线段树RE……求大佬帮忙
#include<cstdio>
#define jump(a) (top[a]==a?fa[a]:top[a])
char buf[1<<22],*S=buf;
char out[1<<22],*T=out;
inline void getint(int &x)
{
x=0;
for (;*S<'0'||*S>'9';S++);
while (*S>='0'&&*S<='9')(x*=10)+=*S++ &15;
}
inline bool getop()
{
for(;*S^'P'&&*S^'Q';S++);
return !(*S^'P');
}
inline void putint(int x)
{
if(x>9)putint(x/10);
*T++=x%10+'0';
}
int n,m;
struct node
{
int to,next;
}g[500021];
int h[100005];
int tot=0,tmp=1;
int to[100005],end[100005];
inline void add(const int &u,const int &v)
{
tot++;
g[tot].to=v;
g[tot].next=h[u];
h[u]=tot;
}
int siz[100005],son[100005],top[100005],d[100005],fa[100005];
class Seg_Tree
{
public:
int l,r,sum,lazy,mid,siz;
Seg_Tree *lc,*rc;
inline Seg_Tree(int l_,int r_)
{
l=l_;
r=r_;
mid=(l+r)>>1;
siz=r-l+1;
}
inline void bt()
{
if(l==r)return;
lc=new Seg_Tree(l,mid);
lc->bt();
rc=new Seg_Tree(mid+1,r);
rc->bt();
}
inline void push_down()
{
if(!lazy)return;
if(l==r)return;
lc->lazy+=lazy;
lc->sum+=lazy*(lc->siz);
rc->lazy+=lazy;
rc->sum+=lazy*(rc->siz);
lazy=0;
}
inline void updata(int l1,int r1,int w)
{
if(l==l1&&r==r1)
{
lazy+=w;
sum+=siz*w;
return;
}
push_down();
if(r1<=mid)lc->updata(l1,r1,w);else
if(l1>mid)rc->updata(l1,r1,w);else
lc->updata(l1,mid,w),rc->updata(mid+1,r1,w);
sum=lc->sum+rc->sum;
}
inline int query(int l1,int r1)
{
if(l==l1&&r==r1)
{
return sum;
}
push_down();
if(r1<=mid)return lc->query(l1,r1);else
if(l1>mid)return rc->query(l1,r1);else
return lc->query(l1,mid)+rc->query(mid+1,r1);
}
}*root[200000];
inline void dfs_1(int k)
{
siz[k]=1;
for(int i=h[k];i;i=g[i].next)
{
int v=g[i].to;
if(v==fa[k])continue;
d[v]=d[k]+1;
fa[v]=k;
dfs_1(v);
siz[k]+=siz[v];
if(siz[v]>siz[son[k]])son[k]=v;
}
}
inline void dfs_2(int k)
{
end[top[k]]=d[k]-d[top[k]];
if(!son[k])return;
top[son[k]]=top[k];
dfs_2(son[k]);
for(int i=h[k];i;i=g[i].next)
{
int v=g[i].to;
if(v^fa[k]&&v^son[k]){
top[v]=v;
to[v]=++tmp;
dfs_2(v);}
}
}
inline void up_path(int a,int b)
{
while(top[a]^top[b])
{
if(d[top[a]]<d[top[b]])
{
a^=b,b^=a,a^=b;
}
root[to[top[a]]]->updata(1,d[a]-d[top[a]]+1,1);
a=fa[top[a]];
}
if(d[a]==d[b])return;
if(d[a]>d[b])
{
a^=b,b^=a,a^=b;
}
root[to[top[a]]]->updata(d[a]-d[top[a]]+2,d[b]-d[top[a]]+1,1);
}
inline int query_path(int a,int b)
{
int ans=0;
while(top[a]^top[b])
{
if(d[top[a]]<d[top[b]])
{
a^=b,b^=a,a^=b;
}
ans+=root[to[top[a]]]->query(1,d[a]-d[top[a]]+1);
a=fa[top[a]];
}
if(d[a]==d[b])return ans;
if(d[a]>d[b])
{
a^=b,b^=a,a^=b;
}
ans+=root[to[top[a]]]->query(d[a]-d[top[a]]+2,d[b]-d[top[a]]+1);
return ans;
}
int main()
{
fread(buf,1,sizeof buf,stdin);
getint(n);
getint(m);
int u,v;
for(int i=1;i<n;i++)
{
getint(u);
getint(v);
add(u,v);
add(v,u);
}
fa[1]=1;
top[1]=1;
to[1]=1;
dfs_1(1);
dfs_2(1);
for(int i=1;i<=tmp;i++)
{
root[i]=new Seg_Tree(1,end[i]+1);
root[i]->bt();
}
while(m--)
{
int u,v;
if(getop())
{
getint(u);
getint(v);
up_path(u,v);
}else
{
getint(u);
getint(v);
putint(query_path(u,v));
*T++ = '\n';
}
}
fwrite(out,T-out,1,stdout);
}
by bdflyao @ 2017-10-11 05:39:04
2333奶牛题
by Leokery @ 2017-10-11 09:47:54
你这个代码好骚啊,这种模板都写了200行。。
by fighter_OI @ 2017-11-09 20:50:01
好吧是我zz了……