jzoj100047-基因变异【位运算,bfs】
生活随笔
收集整理的這篇文章主要介紹了
jzoj100047-基因变异【位运算,bfs】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
一個長度為nnn的序列aaa。
對于一個數每秒可以將一個二進制位取反或異或aaa中的一個數。
qqq個詢問,詢問從xxx變化到yyy最少要多少秒。
解題思路
對于一個x和yx和yx和y,設
xxorw=yx\ xor\ w=yx?xor?w=y
?x=yxorw\Rightarrow x=y\ xor\ w?x=y?xor?w
xxory=wx\ xor\ y=wx?xor?y=w
所以我們對于每個詢問,我們只需要求000變成www的距離就好了。
由于起點只有一個,我們可以用bfsbfsbfs預處理000到www距離。
時間復雜度:O(220(n+20)+q)O(2^{20}(n+20)+q)O(220(n+20)+q)
codecodecode
#include<cstdio> #include<queue> #include<cctype> #define MS 2097151 using namespace std; int n,Q,a[25],v[MS+10]; queue<int> q; inline char Getchar() {static char buf[100000],*p1=buf+100000,*pend=buf+100000;if(p1==pend){p1=buf; pend=buf+fread(buf,1,100000,stdin);if (pend==p1) return -1;}return *p1++; } inline long long read() {char c;int d=1;long long f=0;while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;return d*f; } inline void write(register long long x) {if(x<0)write(45),x=-x;if(x>9)write(x/10);putchar(x%10+48);return; } void bfs()//預處理 {v[0]=1;q.push(0);int y,i;while(!q.empty()){int x=q.front();q.pop();for(i=1;i<=n;i++)//異或a中的數{y=x^a[i];if(!v[y]){v[y]=v[x]+1;q.push(y);}}for(i=0;i<=20;i++)//位數取反{y=x^(1<<i);if(!v[y]){v[y]=v[x]+1;q.push(y);}}} } int main() {freopen("data.in","r",stdin);freopen("data.out","w",stdout);n=read();Q=read();for(int i=1;i<=n;i++)a[i]=read();bfs();for(int i=1;i<=Q;i++) {int x,y,z;x=read();y=read();write(v[x^y]-1);putchar('\n');} }總結
以上是生活随笔為你收集整理的jzoj100047-基因变异【位运算,bfs】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 室内设计的电脑配置要求(室内设计的电脑配
- 下一篇: 5000元电脑配置(配置电脑5000左右