关于空间
  • 板块学术版
  • 楼主Cht_master
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/10/13 23:38
  • 上次更新2023/11/4 03:52:25
查看原帖
关于空间
261046
Cht_master楼主2021/10/13 23:38
  • RT,这是 lz P5214 的代码,实现的是线段树分治。想问明明把空间都加了整体 5 但是 mxQ 开成 10410^4 就炸了开成 104+110^4+1 就能过啊 QwQ 可能我比较蠢是什么细节的问题吧
#include<bits/stdc++.h>
#define inl inline
using namespace std;
const int mxN(5e3),mxM(2e5),mxQ((1e4)+1);

int n,m,q,Ans[mxQ+5];
vector<int>asktm;

struct Edge{int u,v;};
inl bool operator <(Edge a,Edge b){return ((a.u==b.u)?(a.v<b.v):(a.u<b.u));}
//1.重载运算符要写在namespace外面;
//2.std::map默认用'<'运算符比较key,但map<int,vector<int> >没有重载这个运算符,
//所以要实现一个operator'<',或者在第3个模板参数里传入比较器.

namespace Dsu{//以tp为依据:记住没有mrg就没有多余的cancel.
	int an[mxN+5],siz[mxN+5];
	int tp;struct P{int u,v,lnks;}st[mxM+mxQ+5];
	inl void init(){
		tp=0,st[tp].lnks=n;//初始化联通块个数.
		for(int u(1);u<=n;++u)an[u]=u,siz[u]=1;
	}
	inl int Getan(int u){while(an[u]!=u)u=an[u];return u;}
	inl void mrg(int u,int v){
		u=Getan(u),v=Getan(v);
		if(u==v)return;//联通块个数不变.
		if(siz[u]>siz[v])swap(u,v);//siz(u)<siz(v).
		int lstlnks(st[tp].lnks);
		st[++tp]=(P){u,v,lstlnks-1};
		siz[v]+=siz[u],an[u]=v;
	}
	inl void cancel(){
		P top(st[tp--]);
		an[top.u]=top.u,siz[top.v]-=siz[top.u];
	}
}

namespace Sgt{
	#define mid (l+r>>1)
	#define o ID(l,r)
	#define ls ID(l,mid)
	#define rs ID(mid+1,r)
	vector<Edge>e[(mxQ<<1)+5];
	inl int ID(int l,int r){return l+r|l!=r;}
	inl void upd(int l,int r,int ql,int qr,Edge E){
		if(ql<=l&&r<=qr){e[o].push_back(E);return;}
		if(ql<=mid)upd(l,mid,ql,qr,E);
		if(qr>mid)upd(mid+1,r,ql,qr,E);
	}
	inl void upd(int l,int r,Edge E){if(l<=r)upd(0,mxQ,l,r,E);}
	inl void sol(int l,int r){
		using namespace Dsu;
		int lsttp(tp);
		for(int i(0);i<e[o].size();++i)mrg(e[o][i].u,e[o][i].v);
		if(l==r)Ans[l]=st[tp].lnks;else sol(l,mid),sol(mid+1,r);
		while(tp!=lsttp)cancel();
	}
}

namespace G{
	map<Edge,vector<int> >occtm;//tm是关键字.
	//最开始就有的边出现的时间设为0.
	//E这条边在操作序列里出现的时间顺序是occtm[E][].
	inl void add(Edge e,int t){
		if(e.u>e.v)swap(e.u,e.v);//注意这样才能保证一条边的唯一性.
		occtm[e].push_back(t);
	}
	inl void init(){
		for(map<Edge,vector<int> >::iterator it(occtm.begin());it!=occtm.end();++it){
			Edge e(it->first);
			for(int i(0);i<occtm[e].size();i+=2){
				int l(occtm[e][i]),r;
				if(i+1<occtm[e].size())r=occtm[e][i+1];else r=mxQ;
				Sgt::upd(l,r-1,e);
			}
		}
	}
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i(1),u,v;i<=m;++i)scanf("%d%d",&u,&v),G::add((Edge){u,v},0);
	scanf("%d",&q);
	for(int Q(1),u,v;Q<=q;++Q){
		string op;cin>>op;
		if(op[0]=='Q')asktm.push_back(Q);
		else scanf("%d%d",&u,&v),G::add((Edge){u,v},Q);
	}
	G::init(),Dsu::init(),Sgt::sol(0,mxQ);
	for(int i(0);i<asktm.size();++i)printf("%d\n",Ans[asktm[i]]);
	return 0;
}
2021/10/13 23:38
加载中...