zoukankan      html  css  js  c++  java
  • [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('
    ');
    	}
    }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);
    }
    

  • 相关阅读:
    使用nginx在本地查看angular打包项目
    iso与安卓遇到的问题
    Spark 常用的读取数据api
    Spark DataFrame常用API
    spark 词频统计
    spark-shell和spark-sql
    Spark中 RDD、DF、DS的区别与联系
    SparkSQL连接Hive
    spark安装 centos7
    scala安装 centos7
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13039500.html
Copyright © 2011-2022 走看看