題目
你有一個微型處理器,處理器有N個寄存器,編號爲1到N,每個寄存器用二進制存儲一個32位無符號整數(取值範圍爲0到2^32-1)。存儲器能執行以下操作:
指令 描述 Example
1 K M 把寄存器K裏面的數字向右旋轉M位,再把結果寫進寄存器K。 00000000000000000010001111111011
→ (M = 1010) → 11111110110000000000000000001000
(十進制下: 9211 → (M = 10) → 4 273 995 784)
2 K L 把寄存器K和L中的值進行異或運算,結果輸出到系統總線中。 00000000000000000000001111000111
XOR 00000000000001111100000000000111
= 00000000000001111100001111000000
(十進制下: 967 XOR 507 911 = 508 864)
如果有多種解,輸出字典序最小的解(如果兩組解的前K-1個寄存器值相同,第K個寄存器不同,則第K個寄存器的值較小的解字典序更小)。
這題我們可以將每個寄存器的每一位抽出來考慮相互的關係,對於旋轉操作,我們可以維護起始指針位置來還原回去後一一對應考慮。
然後用並查集做。
由於會有後效性,而且不能保證字典序最小,我們不能通過一開始決定x屬於1或屬於0,但可以通過維護x與其並查集頂部位的數是否相同來做。
對於x和y間的關係,若x和y在同一個並查集裏,那麼若x與y不同,而x與並查集頂部相同,y與並查集頂部也相同,則輸出nema(還有x與y相同,同理可推)
若x和y在不同並查集裏,那麼我們通過x與y的關係,以及x與其並查集頂部的關係,和y與其並查集頂部的關係,推得將兩個並查集頂部合併時連邊的權值,若爲1,則說明兩個頂部不同,爲0則相同。(動手推一下)
這些權值在getfather時迭代加起來,得到x與頂部是否相同。(奇數爲不同,偶數爲相同)
最後求答案,從高位枚舉,看一下其所在並查集是否已確定,確定了的話,直接按限制得出,反之爲0,然後按限制強制將頂部賦值。
貼代碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100001
using namespace std;
int n,m;
int fa[N*32][2],s[N];
long long help[32];
bool bz[N*32],ans[N*32];
bool p;
void pre(){
help[0]=1;
for (int i=1;i<32;i++)
help[i]=help[i-1]+help[i-1];
}
int get(int x){
int y;
if (fa[x][0]==x)return x;
y=fa[x][0];
fa[x][0]=get(fa[x][0]);
fa[x][1]=(fa[x][1]+fa[y][1])&1;
return fa[x][0];
}
void init(){
static int x,y,z;
static long long v;
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=32;j++)
fa[(i-1)*32+j][0]=(i-1)*32+j;
p=1;
for (int i=1;i<=m;i++){
scanf("%d %d %d",&x,&y,&z);
if (x==1)
s[y]=(s[y]+z)%32;
else{
scanf("%lld",&v);
for (int i=0;i<32;i++){
static bool e1,e2,e3;
static int xx,yy;
e1=v&help[i];
xx=(y-1)*32+s[y]+1;
yy=(z-1)*32+s[z]+1;
get(xx);
get(yy);
e2=(fa[xx][1]!=fa[yy][1]);
e3=(fa[xx][0]==fa[yy][0]);
if (e3&&e2!=e1)p=0;
else
if (!e3){
fa[fa[xx][0]][1]=(e2!=e1);
fa[fa[xx][0]][0]=fa[yy][0];
}
s[y]=(s[y]+1)%32;
s[z]=(s[z]+1)%32;
}
}
}
}
void write(){
static int x;
static long long y;
if (!p)printf("-1");
else
for (int i=1;i<=n;i++){
y=0;
for (int j=32;j;j--){
x=(i-1)*32+j;
if (!bz[x]){
get(x);
if (bz[fa[x][0]])
ans[x]=(ans[fa[x][0]]^fa[x][1]);
else
bz[fa[x][0]]=1,ans[fa[x][0]]=fa[x][1];
bz[x]=1;
}
y+=ans[x]*help[j-1];
}
printf("%lld ",y);
}
}
int main(){
pre();
init();
write();
return 0;
}