样例爆栈求调
查看原帖
样例爆栈求调
681036
OldDriverTree楼主2024/7/2 22:46

rt,测了下样例提示 *** stack smashing detected ***: terminated

//when you use vector or deque,pay attention to the size of it.
//by OldDirverTree
#include<bits/stdc++.h>
#include<bits/extc++.h>
//#include<atcoder/all>
#define P pair<int,int>
#define int long long
#define mid (l+r>>1)
using namespace std;
using namespace __gnu_pbds;
//using namespace atcoder;
const int N=1e5+1,M=2e5,V=1e9;
struct node { int ls,rs,cnt,sum; }T[N*50];
int tot,tim,root[N],dfn[N],low[N],bel[N];
struct change { int o,x,y; }C[M];
struct edge { int x,y,t; }e[M];
stack<int> s; bool ins[N];
vector<int> a,ans,g[N];
int n,m,q,w[N],fa[N];
map<P,int> tax;

int read() {
	int x=0; bool f=true; char c=0;
	while (!isdigit(c) ) f&=(c!='-'),c=getchar();
	while (isdigit(c) ) x=(x<<3)+(x<<1)+(c&15),c=getchar();
	return f?x:-x;
}
void tarjan(int u) {
	dfn[u]=low[u]=++tim,s.push(u),ins[u]=true; for (int v:g[u])
	if (!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]); else if (ins[v]) low[u]=min(low[u],dfn[v]);
	if (dfn[u]==low[u]) for (int o=0;o^u;o=s.top(),s.pop(),ins[o]=false,bel[o]=u);
}
void solve(int l,int r,int L,int R)
{
	if (l==r||L>R) return; int pos=R;
	for (int i=R;i>=L;i--) if (e[i].t>mid) swap(e[i],e[pos--]);
	for (int x:a) dfn[x]=low[x]=bel[x]=0,g[x].clear(); a.clear(),tim=0;
	for (int i=L;i<=pos;i++) g[e[i].x].push_back(e[i].y),a.push_back(e[i].x),a.push_back(e[i].y);
	for (int x:a) if (!dfn[x]) tarjan(x);
	for (int i=pos;i>=L;i--) if (bel[e[i].x]^bel[e[i].y]||!bel[e[i].x]) e[i].t=mid+1,swap(e[i],e[pos--]);
	for (int i=pos+1;i<=R;i++) {
		if (bel[e[i].x]) e[i].x=bel[e[i].x];
		if (bel[e[i].y]) e[i].y=bel[e[i].y];
	}
	solve(l,mid,L,pos);
	solve(mid+1,r,pos+1,R);
}
int find(int x) {
	return fa[x]^x?fa[x]=find(fa[x]):x;
}
void update(int &rt,int l,int r,int x,int y) {
	if (!rt) rt=++tot; T[rt].cnt+=y,T[rt].sum+=x*y; if (l==r) return;
	x<=mid?update(T[rt].ls,l,mid,x,y):update(T[rt].rs,mid+1,r,x,y);
}
int query(int rt,int l,int r,int k) {
	printf("%lld %lld %lld %lld %lld %lld\n",rt,l,r,k,T[rt].cnt,T[rt].sum);
	if (T[rt].cnt<=k) return T[rt].sum; if (l==r) return k*l;
	if (T[T[rt].rs].cnt>=k) return query(T[rt].rs,mid+1,r,k);
	else T[T[rt].rs].sum+query(T[rt].ls,l,mid,k-T[T[rt].rs].cnt);
}
void merge(int &x,int y) {
	if (!x||!y) return x|=y,void();
	T[x].cnt+=T[y].cnt,T[x].sum+=T[y].sum;
	merge(T[x].ls,T[y].ls),merge(T[x].rs,T[y].rs);
}
main()
{
	n=read(),m=read(),q=read();
	for (int i=1;i<=n;i++) w[i]=read();
	for (int i=1;i<=m;i++) e[i]={read(),read(),0},tax[{e[i].x,e[i].y}]=i;
	for (int i=q;i;i--) {
		C[i]={read(),read(),read()};
		if (C[i].o==1) e[tax[{C[i].x,C[i].y}] ].t=i;
		else if (C[i].o==2) w[C[i].x]+=C[i].y;
	}
	for (int i=1;i<=n;i++) update(root[i],1,V,w[i],1);
	solve(0,q,1,m); for (int i=1;i<=n;i++) fa[i]=i;
	for (int i=0,pos=1;i<=q;i++) {
		while (pos<=m&&e[pos].t==i) { int x=find(e[pos].x),y=find(e[pos].y); pos++; if (x^y) fa[y]=x,merge(root[x],root[y]); }
		if (C[i].o==2) update(root[find(C[i].x)],1,V,w[C[i].x],-1),update(root[find(C[i].x)],1,V,w[C[i].x]-=C[i].y,1);
		if (C[i].o==3) ans.push_back(query(root[find(C[i].x)],1,V,C[i].y) );
	}
	reverse(ans.begin(),ans.end() );
	for (int x:ans) printf("%lld\n",x);
	return 0;
}
2024/7/2 22:46
加载中...