社区讨论

求助未知错误

P5163WD与地图参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lvi729yw
此快照首次捕获于
2024/04/27 22:25
2 年前
此快照最后确认于
2024/04/28 13:00
2 年前
查看原帖
实在调不出错了。请大家分享一些常见的坑,谢谢! 线段树部分:
CPP

inline void modify(int &k,int l,int r,int pos,int d)
{
    if(!k) k=++tot;
    if(l == r) {cnt[k]+=d,sum[k]+=v[l]*d;return;}
    int mid=l+r>>1;
    if(pos <= mid) modify(lc[k],l,mid,pos,d);
    else modify(rc[k],mid+1,r,pos,d);
    cnt[k]=cnt[lc[k]]+cnt[rc[k]];
    sum[k]=sum[lc[k]]+sum[rc[k]];
    return;
}

inline long long query(int k,int l,int r,int need)
{
    if(l == r) return 1ll*need*v[l];
    int mid=l+r>>1,cr=cnt[rc[k]];
    if(need <= cr) return query(rc[k],mid+1,r,need);
    return sum[rc[k]]+query(lc[k],l,mid,need-cr);
}

inline int merge(int x,int y)
{
    if(!x || !y) return x+y;
    cnt[x]+=cnt[y],sum[x]+=sum[y];
    lc[x]=merge(lc[x],lc[y]);
    rc[x]=merge(rc[x],rc[y]);
    return x;
}

整体二分部分:
CPP

inline void link(int x,int y,int t)
{
    int fx=find(x),fy=find(y);
    if(fx == fy) return;
    if(sz[fx] > sz[fy]) swap(fx,fy);
    sz[fy]+=sz[fx],fa[fx]=fy;
    if(t) rt[fy]=merge(rt[fy],rt[fx]);
    done[++lim]=(edge){fx,fy};
    return;
}

inline void tarjan(int x)
{
    dfn[x]=low[x]=++totdfn;
    sta[++top]=x,insta[x]=true;
    for(int to:go[x])
        if(!dfn[to]) tarjan(to),low[x]=min(low[x],low[to]);
        else if(insta[to]) low[x]=min(low[x],dfn[to]);
    if(dfn[x] != low[x]) return;
    sta[top+1]=0;
    while(sta[top+1] != x)
    {
        int v=sta[top--];
        link(v,x,0),insta[v]=false;
    }
    return;
}

inline void undone(int lst)
{
    while(lim > lst)
    {
        edge nw=done[lim--];
        sz[nw.fy]-=sz[nw.fx];
        fa[nw.fx]=nw.fx;
    }
    return;
}

inline void solve(int l,int r,vector<int> nw)
{
    if(!nw.size() || l > r) return;
    if(l == r) {for(int x:nw) ok[x]=l;return nw.clear();}
    int mid=l+r>>1,sz=nw.size(),cpy=lim;
    Down(i,sz-1,0) if(e[nw[i]].ti > mid)
    {
        int x=find(e[nw[i]].f);
        int y=find(e[nw[i]].t);
        go[x].push_back(y);
        nd.push_back(x),nd.push_back(y);
    }for(int x:nd) if(!dfn[x]) tarjan(x);
    for(int x:nd) dfn[x]=0,go[x].clear();
    vector<int> nl,nr;
    For(i,0,sz-1)
    {
        int x=e[nw[i]].f,y=e[nw[i]].t;
        if(e[nw[i]].ti <= mid) nl.push_back(nw[i]);
        else if(find(x) == find(y)) nr.push_back(nw[i]);
        else nl.push_back(nw[i]);
    }nw.clear(),nd.clear(),totdfn=0;
    solve(l,mid,nl),undone(cpy);
    return solve(mid+1,r,nr);
}

主函数部分:
CPP

    n=read(),m=read(),q=read();
    For(i,1,n) w[i]=read(),v[++num]=w[i];
    For(i,1,m)
    {
        e[i].f=read(),e[i].t=read();
        id[e[i].f][e[i].t]=i;
    }
    For(i,1,q)
    {
        int opt=read(),a=read(),b=read();
        if(opt == 1) e[id[a][b]].ti=i-1;
        if(opt == 2) w[a]+=b,v[++num]=w[a];
        ch[i]=(C){opt,a,b};
    }sort(v+1,v+num+1);
    num=unique(v+1,v+num+1)-v-1;
    For(i,1,m) if(!e[i].ti) e[i].ti=q;
    For(i,1,m) init.push_back(i);
    sort(init.begin(),init.end(),rule);
    For(i,1,n) fa[i]=i,sz[i]=1;
    solve(0,q,init);
    For(i,1,m) h[ok[i]].push_back(i);
    For(i,1,n)
    {
        int pos=lower_bound(v+1,v+num+1,w[i])-v;
        modify(rt[i],1,num,pos,1);
    }
    Down(i,q,1)
    {
        for(int id:h[i]) link(e[id].f,e[id].t,1);
        if(ch[i].opt == 2)
        {
            int pre=lower_bound(v+1,v+num+1,w[ch[i].a])-v;
            int x=find(ch[i].a);w[ch[i].a]-=ch[i].b;
            int nxt=lower_bound(v+1,v+num+1,w[ch[i].a])-v;
            modify(rt[x],1,num,pre,-1);
            modify(rt[x],1,num,nxt,1);
        }
        if(ch[i].opt == 3)
        {
            int x=find(ch[i].a);
            if(cnt[rt[x]] <= ch[i].b) ans[i]=sum[rt[x]];
            else ans[i]=query(rt[x],1,num,ch[i].b);
        }
    }
    For(i,1,q) if(ch[i].opt == 3)
        printf("%lld\n",ans[i]);
    return 0;

回复

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

正在加载回复...