hdu-5637 Transform(位运算+bfs)

Posted LittlePointer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-5637 Transform(位运算+bfs)相关的知识,希望对你有一定的参考价值。

题目链接:

Transform

Time Limit: 4000/2000 MS (Java/Others)    

Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 685    Accepted Submission(s): 244


Problem Description
A list of n integers are given. For an integer x you can do the following operations:

+ let the binary representation of x be b31b30...b0¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯, you can flip one of the bits.
+ let y be an integer in the list, you can change x to xy, where  means bitwise exclusive or operation.

There are several integer pairs (S,T). For each pair, you need to answer the minimum operations needed to change S to T.
 

 

Input
There are multiple test cases. The first line of input contains an integer T (T20), indicating the number of test cases. For each test case:

The first line contains two integer n and m (1n15,1m105) -- the number of integers given and the number of queries. The next line contains nintegers a1,a2,...,an (1ai105), separated by a space.

In the next m lines, each contains two integers si and ti (1si,ti105), denoting a query.
 

 

Output
For each test cases, output an integer S=(i=1mizi) mod (109+7), where zi is the answer for i-th query.
 

 

Sample Input
1
3 3
1 2 3
3 4
1 2
3 9
 

 

Sample Output
10
 
 
题意:
 
两种操作,一种是是x^y,y是ai,还有一种是改变x的二进制位中的一位,相当于异或一个2的j次方(j=0,1,2,3,4...);
问s到t最少需要多少次,ans=sigama(i*zi)mod(1e9+7);
 
 
思路:
 
啊啊啊啊啊,自己又是不知道该怎么做,最后看了给的题解说只跟s^t有关才反应过来;这跟异或运算的性质有关;
s^x^y^z^w^...^q=t;假设这是最少的流程,等价于0^x^y^z^w..^q=s^t;就是0到s^t的最少次操作;然后用bfs把所有<=1e5都找出来;
异或运算真神奇;不过我不会.....啊啊啊啊;
 
 
AC代码:
 
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,l,r,a[100],num[300010],flag[300010];
const int mod=1e9+7;
queue<int>qu;
int bfs()
{
    memset(flag,0,sizeof(flag));
    for(int i=1;i<=2e5;i*=2)
    {
        a[n++]=i;
    }
    qu.push(0);
    num[0]=0;
    flag[0]=1;
   while(!qu.empty())
   {
       int top=qu.front();
       qu.pop();
       for(int i=0;i<n;i++)
       {
           if(!flag[a[i]^top])
           {
               qu.push(a[i]^top);
               num[a[i]^top]=num[top]+1;
               flag[a[i]^top]=1;
           }
       }
   }
}
int main()
{
   int t;
   scanf("%d",&t);
   while(t--)
   {
       scanf("%d%d",&n,&m);
       for(int i=0;i<n;i++)
       {
           scanf("%d",&a[i]);
       }
       bfs();
       ll ans=0;
       for(int i=1;i<=m;i++)
       {
           scanf("%d%d",&l,&r);
          // cout<<num[l^r]<<" "<<i
           ans+=(ll)(num[l^r]*i);
           ans%=mod;
       }
        cout<<ans<<"\n";

   }

    return 0;
}

 

 

以上是关于hdu-5637 Transform(位运算+bfs)的主要内容,如果未能解决你的问题,请参考以下文章

位运算

标志寄存器的状态标志

C++ STL transform 函数说明

Fast Walsh-Hadamard Transform——快速沃尔什变换

剑指offer:二进制中的1

四则运算