线段树分治求优化空间
查看原帖
线段树分治求优化空间
289304
HAuCl4楼主2023/5/2 20:23

RT,我wa+re40,目测原因是数组开小了,但数组开大了又 MLE 了,求优化/调。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lc (rt<<1)
#define rc (rt<<1|1)
const int Len=1001;//!
typedef bitset<Len+3> bs;
const int N=505,M=505;
void output(string x)
{
	bool ok=0;
	for(int i=0;i<x.size();i++)
	{
		if((!ok)&&x[i]=='1') ok=1;
		if(ok) putchar(x[i]);
	}
	if(!ok) putchar('0');
	putchar('\n');
}
bool operator >(bs a,bs b)
{
	return a.to_string()>b.to_string();
}
struct linear_basis{
	bs d[M];
	void max_xor()
	{
		bs ans(0);
		for(int i=Len;i>=0;i--)
			if(!ans[i]&&d[i].any()) ans^=d[i];
		output(ans.to_string());
	}	
}B[M<<2];
void insert(bs x,int id)
{
	for(int i=Len;i>=0;i--)
	{
		if(x.test(i))
		{
			if(B[id].d[i].none())
			{
				B[id].d[i]=x;
				break;
			}
			else x^=B[id].d[i];
		}
	}
}
struct node{
	int x,y,s,t;
	bs w;
//	void print()
//	{
//		printf("(%d <-> %d) s=%d t=%d w=",x,y,s,t);
//		cout<<w.to_string()<<endl;
//	}
};
typedef vector<node> ve;
struct edge{
	int T,x,y;
	bs w;
}G[M];
ve tag[M<<2],init,v;
void update(int rt,int l,int r,node a)
{
	if(l>r) return;
	if(a.s<=l&&a.t>=r)
	{
//		printf("rt=%d [%d,%d] pb ",rt,l,r);
//		a.print();
		tag[rt].push_back(a);
		return;
	}
	int mid=(l+r)>>1;
	if(a.s<=mid) update(lc,l,mid,a);
	if(a.t>mid) update(rc,mid+1,r,a); 
}
int n,m;
int T=0;
int f[N],sz[N];
bs dis[N],k;
int find(int x)
{
	while(x!=f[x])
	{
		k^=dis[x];
		x=f[x];
	}
	return x;
}
void solve(int rt,int l,int r)
{
	if(l>r) return;
//	printf("SOLVE %d [%d,%d]\n",rt,l,r);
//	for(int i=1;i<=n;i++)
//	{
//		printf("%d: f=%d sz=%d dis=",i,f[i],sz[i]);
//		output(dis[i].to_string());
//	}
	int mid=(l+r)>>1;
	v=tag[rt];
	queue<pair<short,bs> > d;
	B[rt]=B[rt/2];
	for(int i=0;i<v.size();i++)
	{
//		printf("(%d <-> %d) s=%d t=%d w=",v[i].x,v[i].y,v[i].s,v[i].t);
//		cout<<v[i].w.to_string()<<endl;
		k.reset();
		int x=find(v[i].x),y=find(v[i].y);
//		printf("x=%d y=%d\n",x,y);
		if(x==y)//circuit
		{
		/*	printf("x: "); output(dis[v[i].x].to_string());
			printf("y: "); output(dis[v[i].y].to_string());
			printf("w: "); output(v[i].w.to_string());
			printf("tot: "); output((dis[v[i].x]^dis[v[i].y]^v[i].w).to_string());
			insert(dis[v[i].x]^dis[v[i].y]^v[i].w,rt);*/
//			printf("k: "); output(k.to_string());
//			printf("tot: "); output((k^v[i].w).to_string());
			insert((k^v[i].w),rt);
		}
		else//merge
		{
			if(sz[x]>sz[y]) swap(x,y);
			f[x]=y; sz[y]+=sz[x];
			dis[x]=k^v[i].w;
			d.push(make_pair(x,v[i].w));
		}
//		printf("Now-----------\n");
//		for(int i=1;i<=n;i++)
//		{
//			printf("%d: f=%d sz=%d dis=",i,f[i],sz[i]);
//			output(dis[i].to_string());
//		}
//		printf("**************\n\n");
	}
	if(l==r) B[rt].max_xor();
	else solve(lc,l,mid),solve(rc,mid+1,r);
	bs tmp;
	while(!d.empty())
	{
		int x=d.front().first; 
		tmp=d.front().second;
		d.pop();
		sz[f[x]]-=sz[x];
		dis[x]^=tmp;
	}
}
int main()
{
	int Q;
	scanf("%d%d%d",&n,&m,&Q);
	for(int i=1;i<=n;i++) f[i]=i,sz[i]=1;
	bs tmp;
	int ta,tb;
	char ch[15];
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&ta,&tb);
		cin>>tmp;
		init.push_back(node{ta,tb,0,Q,tmp});
//		cout<<tmp.to_string()<<endl;
	}
	int tot=0;
	for(int i=1;i<=Q;i++)
	{
		scanf("%s",ch);
		T++;
		switch(ch[1])
		{
			case 'd':{
				scanf("%d%d",&ta,&tb);
				cin>>tmp;
				tot++;
				G[tot]=edge{T,ta,tb,tmp};
				break;
			}
			case 'a':{
				scanf("%d",&ta);
				init.push_back(node{G[ta].x,G[ta].y,G[ta].T,T-1,G[ta].w});
				G[ta].T=-1;
				break;
			}
			case 'h':{
				scanf("%d",&ta);
				cin>>tmp;
				init.push_back(node{G[ta].x,G[ta].y,G[ta].T,T-1,G[ta].w});
				G[ta].T=T;
				G[ta].w=tmp;
				break;
			}
		}
	}
	for(int i=1;i<=tot;i++)
		if(G[ta].T!=-1) init.push_back(node{G[ta].x,G[ta].y,G[ta].T,T,G[ta].w});
	for(int i=0;i<init.size();i++)
		update(1,0,T,init[i]); 
	solve(1,0,T);
	return 0;
}
2023/5/2 20:23
加载中...