蒟蒻求救

P3038 [USACO11DEC] Grass Planting G

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了……


|