社区讨论

TLE 40pts 求优化

P9233[蓝桥杯 2023 省 A] 颜色平衡树参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mhjuagb6
此快照首次捕获于
2025/11/04 08:37
4 个月前
此快照最后确认于
2025/11/04 08:37
4 个月前
查看原帖
rt。平常这么写的 dsu on tree 都不会被卡这么久,复杂度也不可能有问题啊
CPP
#include<bits/stdc++.h>
// #define int long long
using namespace std;
typedef long long ll;
const int MAXN=200005,mod=998244353,inf=0x3f3f3f3f;
int n;
#define toi (e[i].to)
// #define roi (e[i^1].to)
#define fore(now,i) for(int i=head[now];i;i=e[i].next)
int cnt=0,head[MAXN];
struct EDGE{
    int to,next;
}e[MAXN];
inline void addedge(int u,int v){
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
int c[MAXN],son[MAXN],sz[MAXN],l[MAXN],r[MAXN],dfncnt=0,node[MAXN];
void dfs0(int now){
    sz[now]=1;
    node[l[now]=++dfncnt]=now;
    fore(now,i){
        dfs0(toi);
        sz[now]+=sz[toi];
        if(sz[toi]>sz[son[now]])
            son[now]=toi;
    }
    r[now]=dfncnt;
}
int num[MAXN],sum[MAXN];
inline void add(int now){
    now=c[now];
    --sum[num[now]];
    ++num[now];
    ++sum[num[now]];
}
inline void del(int now){
    now=c[now];
    --sum[num[now]];
    --num[now];
    ++sum[num[now]];
}
int ans=0;
bool vis[MAXN];
void dfs(int now,bool keep){
    fore(now,i)
        dfs(toi,0);
    if(son[now])
        dfs(son[now],1);
    // cerr<<"now done "<<now<<"\n";
    fore(now,i)
        if(toi!=son[now])
            for(int j=l[toi];j<=r[toi];j++)
                add(node[j]);
    add(now);
    // cerr<<"now in "<<now<<": its "<<num[c[now]]<<"*"<<sum[num[c[now]]]<<" and "<<sz[now]<<"\n";
    if(!vis[now])
        ans+=(num[c[now]]*sum[num[c[now]]]==sz[now]);
    vis[now]=1;
    if(!keep)
        for(int i=l[now];i<=r[now];i++)
            del(node[i]);
}
ll read(){
    ll reans=0;char ch=getchar();
    while(!isdigit(ch)){ch=getchar();}
    while(isdigit(ch))reans=(reans<<1)+(reans<<3)+(ch^48),ch=getchar();
    return reans;
}
void write(ll x){
    if(x<10)return (void)putchar(x+48);
    write(x/10);
    putchar(x%10+48);
}
signed main(){
    // cin.tie(nullptr)->sync_with_stdio(false);
    // cin>>n;
    n=read();
    for(int i=1,fa;i<=n;i++){
        // cin>>c[i]>>fa;
        c[i]=read(),fa=read();
        if(fa)
            addedge(fa,i);
    }
    dfs0(1);
    dfs(1,1);
    // for(int i=1;i<=n;i++)
    //     cerr<<ans[i]<<" ";
    // cout<<ans[1];
    write(ans);
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...