萌新,刚学OI,树剖,没过样例,求查错

P3038 [USACO11DEC] Grass Planting G

wubaiting2020 @ 2019-09-06 18:32:14

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#define countt(k) (tree[k].r-tree[k].l+1)
#define LL long long
#define _max(x,y) (x>y?x:y)
using namespace std;
const int INF=0x3f3f3f3f,MAXX=100005;
int read()
{
   int s=0,bj=0;
   char ch=getchar();
   while(ch<'0'||ch>'9')bj|=(ch=='-'),ch=getchar();
   while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
   return bj?-s:s;
}
void printnum(int x)
{
    if(x>9)printnum(x/10);
    putchar(x%10^48);
}
void print(int x,char ch)
{
    if(x<0){putchar('-');x=-x;}
    printnum(x);putchar(ch);
}
int n,m;
struct node{int nx,to;}w[MAXX<<1];int ecnt,h[MAXX];
struct Segment_Tree{int l,r,sum,add;}tree[MAXX<<2];
void AddEdge(int x,int y){w[++ecnt].to=y;w[ecnt].nx=h[x];h[x]=ecnt;}
int prt[MAXX],size[MAXX],dep[MAXX],top[MAXX],tid[MAXX],cnt,son[MAXX];
void DFS1(int x,int fa,int depth)
{
    prt[x]=fa;size[x]=1;dep[x]=depth;
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(y^fa){DFS1(y,x,depth+1);size[x]+=size[y];if(size[son[x]]<size[y])son[x]=y;}
    }
}
void DFS2(int x,int topp)
{
    top[x]=topp;tid[x]=++cnt;
    if(!son[x])return;
    DFS2(son[x],topp);
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(y^prt[x]&&y^son[x])DFS2(y,y);
    }
}
void pushup(int k){tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;}
void pushdown(int k)
{
    if(tree[k].add)
    {
        tree[k<<1].add+=tree[k].add;tree[k<<1|1].add+=tree[k].add;
        tree[k<<1].sum+=countt(k<<1)*tree[k].add;tree[k<<1|1].sum+=countt(k<<1|1)*tree[k].add;
        tree[k].add=0;
    }
}
void Build(int k,int l,int r)
{
    tree[k].l=l;tree[k].r=r;
    if(l==r)return;
    int mid=(l+r)>>1;
    Build(k<<1,l,mid);Build(k<<1|1,mid+1,r);
}
int ans=0;
void Add(int k,int l,int r)
{
    if(l>tree[k].r||r<tree[k].l)return;
    if(l<=tree[k].l&&r>=tree[k].r){tree[k].sum+=countt(k);tree[k].add++;return;}
    pushdown(k);
    Add(k<<1,l,r);Add(k<<1|1,l,r);
    pushup(k);
}
int Ask(int k,int x)
{
    if(tree[k].l==tree[k].r)return tree[k].sum;
//  if(x>tree[k].r||x<tree[k].l)return 0;
    int mid=(tree[k].l+tree[k].r)>>1;
    pushdown(k);
    if(x<=mid)return Ask(k<<1,x);
    else return Ask(k<<1|1,x);
}
void Add_Edge(int x,int y)
{
    while(top[x]^top[y])
    {
        if(dep[top[x]]<dep[top[y]])swap(x,y);
//      cout<<"ADD"<<tid[top[x]]<<" "<<tid[x]<<endl;
        Add(1,tid[top[x]],tid[x]);
        x=prt[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
//  cout<<"ADD"<<tid[x]+1<<" "<<tid[y]<<endl;
    Add(1,tid[x]+1,tid[y]);
}
int main()
{
    n=read();m=read();
    for(int i=1;i<n;i++)
    {
        int x=read(),y=read();
        AddEdge(x,y);AddEdge(y,x);
    }
    DFS1(1,0,1);
    DFS2(1,1);
    Build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        char ch[2];int x,y;
        scanf("%s",ch);
        x=read();y=read();
        if(ch[0]=='P')Add_Edge(x,y);
        else print(Ask(1,(dep[x]>dep[y])?x:y),'\n');
    }
//  for(int i=1;i<=4*n;i++)cout<<tree[i].sum<<" ";
    return 0;
}

by ZhuMingYang @ 2019-09-06 18:52:15

@Soledad 有任何区别吗


by wubaiting2020 @ 2019-09-06 18:53:12

有的 @ZhuMingYang


by Soledad_S @ 2019-09-06 18:53:48

@ZhuMingYang AC既是证明


by ZhuMingYang @ 2019-09-06 18:54:58

@Soledad 我怎么没看出来哪里变了


by MC方块人 @ 2019-09-06 18:55:46

刚学OI……


by wubaiting2020 @ 2019-09-06 18:56:44

@ZhuMingYang 树剖线段树里面是dfs序……


by Soledad_S @ 2019-09-06 18:57:31

@ZhuMingYang 我只是把他的代码粘下来了,实际上应该是

        else print(Ask(1,tid[(dep[x]>dep[y])?x:y]),'\n');

by ZhuMingYang @ 2019-09-06 18:58:17

哦哦。。。


上一页 |