树剖 dfs部分神奇RE

P3038 [USACO11DEC] Grass Planting G

yinhee @ 2022-07-15 06:46:19

rt,对着洛谷板子改过,基本上没区别,但是在第一次dfs的时候就re。求调

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<queue>
#define run int T;scanf("%d",&T);while(T--)solve
#define lb lower_bound
using namespace std;
typedef long long ll;
const int maxn=2e5+7,inf=2147483647;
const int mod=1;
int n,m,e[maxn<<2],tag[maxn<<2];
int siz[maxn],wt[maxn],dep[maxn],fa[maxn];
int cnt,dfn[maxn],rk[maxn],top[maxn];
int tot,head[maxn];
int x,y,z,ans;
bool vis[maxn];
struct node{
    int to,nxt;
}edge[maxn];
void add(int u,int v){
    edge[++tot]={v,head[u]};
    head[u]=tot;
}
void dfs1(int now){
//  return;
    siz[now]=1;
    for(int i=head[now];i;i=edge[i].nxt){
        int v=edge[i].to;
        if(v!=fa[now]){
            fa[v]=now;
            dep[v]=dep[now]+1;
            dfs1(v);
            siz[now]+=siz[v];
            if(siz[v]>=siz[wt[now]])wt[now]=v;
        }
    }
}
void dfs2(int now,int t){
    dfn[now]=++cnt;
    rk[cnt]=now;
    top[now]=t;
    if(!wt[now])return;
    dfs2(wt[now],t);
    for(int i=head[now];i;i=edge[i].nxt){
        int v=edge[i].to;
        if(v!=fa[now]&&v!=wt[now])dfs2(v,v);
    }
}
inline void pushup(int now){e[now]=e[now<<1]+e[now<<1|1];}
inline void pushdown(int l,int r,int now){
    if(!tag[now])return;
    int mid=l+r>>1;
    tag[now<<1]+=tag[now];tag[now<<1|1]+=tag[now];
    e[now<<1]+=(mid-l+1)*tag[now];e[now<<1|1]+=(r-mid)*tag[now];
    tag[now]=0;
}
void update(int l,int r,int now){
    if(l>=x&&r<=y){
        e[now]+=r-l+1;
        tag[now]++;
        return;
    }
    pushdown(l,r,now);
    int mid=l+r>>1;
    if(x<=mid)update(l,mid,now<<1);
    if(y>mid)update(mid+1,r,now<<1|1);
    pushup(now);
}
void query(int l,int r,int now){
    if(l>=x&&r<=y){
        ans+=e[now];
        return;
    }
    pushdown(l,r,now);
    int mid=l+r>>1;
    if(x<=mid)query(l,mid,now<<1);
    if(y>mid)query(mid+1,r,now<<1|1);
}
void change(int l,int r){
//  cout<<top[l]<<top[r]<<endl;
    while(top[l]!=top[r]){
        if(dep[top[l]]<dep[top[r]])swap(l,r);
        x=dfn[top[l]]-1,y=dfn[l]-1;
        update(1,n,1);
        l=fa[top[l]];
    }
    if(dep[l]>dep[r])swap(l,r);
    x=dfn[l],y=dfn[r]-1;
    update(1,n,1);
}
void ask(int l,int r){
    while(top[l]!=top[r]){
        if(dep[top[l]]<dep[top[r]])swap(l,r);
        x=dfn[top[l]]-1,y=dfn[l]-1;
        query(1,n,1);
        l=fa[top[l]];
    }
//  cout<<l<<r<<endl;
    if(dep[l]>dep[r])swap(l,r);
    x=dfn[l],y=dfn[r]-1;
    query(1,n,1);
}
signed main(){
//  freopen("P3038_4.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1,u,v;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    dep[1]=1;
    dfs1(1);dfs2(1,1);
    for(int i=1;i<=m;i++){
        char op=getchar();
        while(op!='P'&&op!='Q')op=getchar();
        scanf("%d%d",&x,&y);
        if(op=='Q'){
            ans=0;
            ask(x,y);
            printf("%d\n",ans);
        }else{
            change(x,y);
        }
    }
}

请忽略我看错题把单点查询打成区间查询


by yinhee @ 2022-07-15 08:00:49

@liruiduan2 您是说根节点吗?这个不影响的吧


by 清烛 @ 2022-07-15 08:01:07

如果是命令行调试的话,可以在编译选项里面加 -Wl,--stack=100000000 来开无限栈。


by yinhee @ 2022-07-15 08:12:44

确认了一下,好像是爆栈了。请问怎么解决?


by yinhee @ 2022-07-15 08:12:59

@清烛


by yinhee @ 2022-07-15 08:13:10

@Mikefeng


by Mikefeng @ 2022-07-15 08:14:08

开无限栈啊(如果你用c++自带调试当我没说


by Mikefeng @ 2022-07-15 08:25:49

不知道洛谷的在线IDE有没有无限栈


by yinhee @ 2022-07-15 08:27:49

@Mikefeng 交题能用无限栈吗?


by Mikefeng @ 2022-07-15 08:37:15

交题是有的


by yinhee @ 2022-07-15 08:40:25

真无语了,明明没爆栈,dev上偏就在dfs1挂掉了


上一页 | 下一页