社区讨论
求助未知错误
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 条回复,欢迎继续交流。
正在加载回复...