zoukankan      html  css  js  c++  java
  • Agc016_D XOR Replace

    传送门

    题目大意

    给定两个长为$n$的序列$A,B$你可以进行若干组操作,每次操作选定一各位置$x$,令$A_x$等于$A$的异或和。

    问能否通过一定操作使得$A$成为$B$,如果能,求最小操作书数。

    题解

    考虑操作的意义,找找规律就知道第一次操作是把一个数变为异或和,以后每次操作都是把这个数变成上次操作位置原来的数,因此由以下几个结论。

    一定有解,当且仅当排序后$A,B$完全相同或至多一个数不相同且$B$中的那个数是$A$所有元素的异或和。

    所以判无解有一个技巧,令$A_{n+1}=A$的异或和,$B$同理,仔细想一想不难发现条件成立当且仅当新的$A,B$在排序后完全相同。

    此处应$Orzspace Hwcspace Otz$。

    接下考虑把每一个出现的数看做一个点,对于所有$A_i e B_i$,我们知道操作它之前一定会先操作一个$j$使得$A_j=B_i$,所以我们就连一条$(B_i ightarrow A_i)$的边,最终除了第一步,每次操作可以视为沿着当前的点走一条边,目的是走完所有边至少一次。不难想到所有的弱连通块都是由若干个环所构成的强联通块,所以出去第一次操作所走完的代价是边数,而第一次操作需进入一个连通块,当且仅当连通块中有$A$的异或和时不需要走这一步。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<set>
    #define LL long long
    #define M 200020
    using namespace std;
    namespace IO{
    	const int BS=(1<<20); int Top=0;
    	char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
    	char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS-1,stdin);} return (HD==TL)?EOF:*HD++;}
    	void write(int x){
    		if(!x){putchar('0');return;} if(x<0) x=-x,putchar('-');
    		while(x) SS[++Top]=x%10,x/=10;
    		while(Top) putchar(SS[Top]+'0'),--Top;
    	}
    	int read(){
    		int nm=0,fh=1; char cw=Getchar();
    		for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
    		for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
    		return nm*fh;
    	}
    }
    using namespace IO;
    int ans,n,m,A[M],B[M],C[M],D[M],f[M],sz[M];
    int fd(int x){return x==f[x]?x:f[x]=fd(f[x]);}
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++) C[i]=A[i]=read(),A[n+1]^=A[i];
    	for(int i=1;i<=n;i++) D[i]=B[i]=read(),B[n+1]^=B[i];
    	n++,C[n]=A[n],D[n]=B[n],sort(C+1,C+n+1),sort(D+1,D+n+1);
    	for(int i=1;i<=n;i++) if(C[i]!=D[i]){write(-1),putchar('
    ');return 0;}
    	m=unique(C+1,C+n+1)-(C+1); for(int i=0;i<=m+2;i++) f[i]=i,sz[i]=1;
    	for(int i=1;i<=n;i++){
    		ans+=(A[i]!=B[i]&&i<n);
    		A[i]=lower_bound(C+1,C+m+1,A[i])-C;
    		B[i]=lower_bound(C+1,C+m+1,B[i])-C;
    		int x=fd(A[i]),y=fd(B[i]); if(x!=y) f[x]=y,sz[y]+=sz[x];
    	}
    	for(int i=1;i<=n;i++) ans+=(fd(i)==i&&sz[fd(i)]>1);
    	if(A[n]!=B[n]||sz[fd(A[n])]>1) ans--;
    	write(ans),putchar('
    '); return 0;
    }
  • 相关阅读:
    zoj 1797 Least Common Multiple
    poj 3233 Matrix Power Series
    使用membership(System.Web.Security)来进行角色与权限管理 (转)
    flashplayer9的全屏模式
    AJAX1.0的UpdateProgress使用
    ASP.NET 2.0中的成员管理与角色管理 (续)
    ASP.net AJAX 调用PageMethods实例
    关于模式窗体的缓存问题的解决方案
    win2003服务器中:无法连接ACCESS数据库/sql数据库正常 && .net程序生成的dll文件拒绝访问问题
    js event 详解
  • 原文地址:https://www.cnblogs.com/OYJason/p/9816765.html
Copyright © 2011-2022 走看看