HDU 5637 Transform

39 篇文章 0 订阅
13 篇文章 0 订阅
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  n integers  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
Hint
$3 \to 4$ (2 operations): $3 \to 7 \to 4$ $1 \to 2$ (1 operation): $1 \oplus 3 = 2$ $3 \to 9$ (2 operations): $3 \to 1 \to 9$
最近一直在做pat,做的人都水了,竟然想着暴力能过。。这题可以直接预处理处理所有的状态,然后直接o(1)回答就好了。
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<iostream>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long LL;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 4e4;
int T, n, m, ans;
int a[20], f[maxn], x, y;
bitset<20> t;

int main()
{
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d%d", &n, &m);    
		for (int i = 0; i < n; i++) scanf("%d", &a[i]);
		memset(f, 1, sizeof(f));
		queue<int> p;	p.push(f[0] = 0);
		while (!p.empty())
		{
			int q = p.front();	p.pop();
			for (int i = 0; i < n; i++)
			{
				if (f[q^a[i]]>f[q] + 1)
				{
					f[q^a[i]]=f[q] + 1;
					p.push(q^a[i]);
				}
			}
			for (int i = 0; i < 17; i++)
			{
				if (f[q^(1<<i)]>f[q] + 1)
				{
					f[q ^ (1 << i)] = f[q] + 1;
					p.push(q ^ (1 << i));
				}
			}
		}
		int res = 0;
		for (int k = 1; k <= m; k++)
		{
			scanf("%d%d", &x, &y);
			(res += k*f[x^y]) %= mod;
		}
		printf("%d\n", res);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值