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 x⊕y, 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 (T≤20), indicating the number of test cases. For each test case:

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

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

Output

For each test cases, output an integer S=(∑i=1mi⋅zi) 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;
}
时间: 2024-10-09 13:23:24

hdu-5637 Transform(位运算+bfs)的相关文章

bfs+位运算 hdu 5094 有钥匙的迷宫

题意:给你一个n*m的矩阵,每个格子可以移动到他上下左右四个格子.现在有些格子之间有门或墙.墙不能通过,每个门需要对应的钥匙打开.最多10种门,钥匙分布在某些格子上,走到这些格子上就能拿到钥匙.现在要从(1,1)走到(n,m)问最少要走多少步.如果不能到达输出-1. 样例解释: 4 49 9 1 2 1 3 2 1 2 2 2 0 2 1 2 2 0 2 1 3 1 0 2 3 3 3 0 2 4 3 4 1 3 2 3 3 0 3 3 4 3 0 4 3 4 4 0 2 2 1 2 4 2 1

POJ 1166 The Clocks 位运算与BFS

1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的状态所需要的最小操作数的操作方案: 2.输入输出:输入给出阵列初始状态,0,1,2,3分别表示0,3,6,9:要求输出最快方案的操作序列: 3.分析:IOI 1994的考题,BFS是比较容易想到的方法之一,关键是如何简洁的表示和改变BFS过程中的阵列状态:这里使用位运算的方法:具体如下: 首先一共9

hdu 1882 Strange Billboard(位运算+枚举)

http://acm.hdu.edu.cn/showproblem.php?pid=1882 感觉非常不错的一道题. 给一个n*m(1<=n,m<=16)的矩阵,每一个格子都有黑白两面,当翻一个格子时,它的上下左右都要翻转,问最后使格子全变为白色的最少翻转步数. 仅仅需枚举第一行的状态即可,由于对于第i(i>=2)行j列翻转情况受上一行的制约,仅仅有当上一行也是'X'的时候,该行j列才干翻转,使i-1行j列变为'.',否则i行j列不能翻转.依次进行下去,当最后一行全变为白色,说明翻转成功

HDU 5023 A Corrupt Mayor&#39;s Performance Art(线段树+优美的位运算)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 Problem Description Corrupt governors always find ways to get dirty money. Paint something, then sell the worthless painting at a high price to someone who wants to bribe him/her on an auction, this

HDU 2276 Kiki &amp; Little Kiki 2 (位运算+矩阵快速幂)

HDU 2276 Kiki & Little Kiki 2 (位运算+矩阵快速幂) ACM 题目地址:HDU 2276 Kiki & Little Kiki 2 题意: 一排灯,开关状态已知,每过一秒:第i个灯会根据刚才左边的那个灯的开关情况变化,如果左边是开的,它就会变化,如果是关的,就保持原来状态.问m秒后的状态. 第1个的左边是最后一个. 分析: 转移不好想啊... 变化是这样的: 原来 左边 变化 1 1 0 1 0 1 0 1 1 0 0 0 然后想到 (~原来)^(左边)=变化

HDU 1882 Strange Billboard(位运算)

题目链接 题意 : 给你一个矩阵,有黑有白,翻转一个块可以让上下左右都翻转过来,问最少翻转多少次能让矩阵变为全白. 思路 : 我们从第一行开始枚举要翻转的状态,最多可以枚举到2的16次方,因为你只要第一行的确定了,第二行要翻转的也就确定了,所以第一行的状态决定了最后的状态.看了网上大神,真是让位运算废了啊,,,,,太复杂了...... 1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #

Vijos 1206 CoVH之再破难关 BFS与位运算

1.题意:一个由01组成的4*4的矩阵,可以实现相邻元素交换位置的操作,给出初试状态和目标状态,试求最少操作数的方案: 2.输入输出:输入给出初试矩阵和目标矩阵:要求输出最小操作的次数: 3.分析:输出最小操作数,很容易联想到使用BFS,这里为了方便表示,把4*4的矩阵拉成一个16个数的数组来看,并用一个16位二进制数表示其状态:用位运算来实现交换某两位的状态,另外再稍微注意一下如何在表示"相邻"的概念即可: 1 # include <iostream> 2 # inclu

hdu 2721(字符串处理,位运算 暴力)

Persistent Bits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 201    Accepted Submission(s): 116 Problem Description WhatNext Software creates sequence generators that they hope will produce

【位运算】【BFS】移动玩具

1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2246  Solved: 1246[Submit][Status][Discuss] Description 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动 时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移 动到某人心中的目标状态. Input 前4行表示