[HAOI2017]八纵八横

题目传送门

分析:
一个熟练的OI选手(错乱)会发现询问其实就是在图上找一些环使得异或和最大
(感性分析)链接这些环的路径会因为被经过了偶数次而异或起来被抵消掉
考虑求图上的一颗生成树,因为原图上的高速路不会被取消,图一定连通(否则可以用LCT维护)
有一个结论:
图上任意一个环都可以用若干个生成树上一条路径和一条非树边构成的环异或得来
我们把生成树上一条路径和一条非树边构成的环的值存在非树边上
然后就变成了寻找一系列非树边使得异或和最大
这个直接上线性基
考虑到后面高铁有建成和取消,尝试使用线段树分治或者可回退的线性基
位数高达\(1e3\),用bitset写线性基,与平时写法不大一样
然后就是常规操作了

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<iostream>
#include<map>
#include<bitset>
#include<string>

#define maxn 6005
#define maxm 1005
#define MOD 1000000007
#define bs bitset<maxm>

using namespace std;

inline long long getint()
{
    long long num=0,flag=1;char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    return num*flag;
}

int n,m,q,mb;
int fir[maxn],nxt[maxn],to[maxn],cnt;
struct base{
	bs s[maxm];
	inline void insert(bs x)
	{
		for(int i=mb;~i;i--)if(x[i])
		{
			if(!s[i].any()){s[i]=x;break;}
			else x^=s[i];
		}
	}
	inline void solve()
	{
		bs ans;ans.reset();
		for(int i=mb;~i;i--)if(!ans[i])ans^=s[i];
		int flag=0;
		for(int i=mb;~i;i--)
		{
			if(ans[i])flag=1;
			if(flag)putchar(ans[i]+'0');
        }
		if(!flag)putchar('0');
		putchar('\n');
	}
}B;
bs len[maxn],dis[maxn];
struct node{
	int x,y,l,r;
	bitset<maxm>val;
}E[maxn];
int f[maxn],tot,id[maxn];
vector<int>V[maxn<<2];
string s;

inline int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
inline void newnode(int u,int v,bs w)
{to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,len[cnt]=w;}
inline void dfs(int u,int fa)
{for(int i=fir[u];i;i=nxt[i])if(to[i]!=fa)dis[to[i]]=dis[u]^len[i],dfs(to[i],u);}

inline void update(int i,int l,int r,int ql,int qr,int x)
{
	if(r<ql||qr<l)return;
	if(ql<=l&&r<=qr){V[i].push_back(x);return;}
	int mid=(l+r)>>1;
	update(i<<1,l,mid,ql,qr,x),update(i<<1|1,mid+1,r,ql,qr,x);
}

inline void solve(int i,int l,int r,base T)
{
	for(int j=0;j<V[i].size();j++)T.insert(dis[E[V[i][j]].x]^dis[E[V[i][j]].y]^E[V[i][j]].val);
	if(l==r){T.solve();return;}
	int mid=(l+r)>>1;
	solve(i<<1,l,mid,T),solve(i<<1|1,mid+1,r,T);
}

int main()
{
	n=getint(),m=getint(),q=getint();
	for(int i=1;i<=n;i++)f[i]=i;
	for(int i=1;i<=m;i++)
	{
		int x=getint(),y=getint();cin>>s;
		mb=max(mb,(int)s.size());
		int r1=find(x),r2=find(y);
		if(r1!=r2)f[r1]=r2,newnode(x,y,bs(s)),newnode(y,x,bs(s));
		else E[++tot]=(node){x,y,0,q,bs(s)};
	}
	dfs(1,1);cnt=0;
	for(int i=1;i<=q;i++)
	{
		cin>>s;
		if(s[0]=='A')
		{
			int x=getint(),y=getint();cin>>s;
			mb=max(mb,(int)s.size());
			E[++tot]=(node){x,y,i,q,bs(s)},id[++cnt]=tot;
		}
		else if(s[1]=='a')
		{
			int x=getint();
			E[id[x]].r=i-1,id[x]=0;
		}
		else
		{
			int x=getint();cin>>s;
			mb=max(mb,(int)s.size());
			E[id[x]].r=i-1;
			E[++tot]=(node){E[id[x]].x,E[id[x]].y,i,q,bs(s)};
			id[x]=tot;
		}
	}
	for(int i=1;i<=tot;i++)update(1,0,q,E[i].l,E[i].r,i);
	solve(1,0,q,B);
}

posted @ 2020-06-03 18:58  Izayoi_Doyo  阅读(237)  评论(0编辑  收藏  举报