您的位置:首页 > 其它

HDU 5637 Transform 最短路

2016-03-05 22:32 225 查看

Transform

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=5637

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 n integers 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

Hint

题意

给出nn个整数, 对于一个整数xx, 你可以做如下的操作若干次:

令x的二进制,你可以翻转其中一个位.

令y是给出的其中一个整数, 你可以把x变为x⊕y, 其中⊕表示位运算里面的异或操作.

现在有若干整数对(S, T), 对于每对整数你需要找出从S变成T的最小操作次数.

题解:

首先从S到T,等价于从0到S^T

然后我们一开始预处理[0,1e5]所有点的图

然后从0开始跑dij就好了

这样跑出来答案就可以O(1)了

注意S^T是可能大于1e5的

代码

#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int maxn = 1e6+7;
const int mod = 1e9+7;
vector<int> E[maxn];
int s[maxn],t[maxn];
int vis[maxn];
int dis[maxn];
int a[16];
void init()
{
for(int i=0;i<maxn;i++)
E[i].clear();
memset(vis,0,sizeof(vis));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=0;i<=1e5;i++)
{
vector<int> tmp;
for(int j=1;j<=n;j++)
{
int p = i^a[j];
E[i].push_back(p);
}
for(int j=0;j<=16;j++)
{
int p=i^(1<<j);
E[i].push_back(p);
}
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&s[i],&t[i]);
t[i]^=s[i];
}
priority_queue<pair<int,int> > Q;
for(int i=0;i<maxn;i++)
dis[i]=1e9;
dis[0]=0;
Q.push(make_pair(0,0));
while(!Q.empty())
{
pair<int,int> now = Q.top();
int x = now.second;
Q.pop();
if(vis[x])continue;
vis[x]=1;
for(int i=0;i<E[x].size();i++)
{
int v = E[x][i];
if(dis[v]>dis[x]+1)
{
dis[v]=dis[x]+1;
Q.push(make_pair(-dis[v],v));
}
}
}
long long ans = 0;
for(int i=1;i<=m;i++)
ans=(ans+i*dis[t[i]])%mod;
printf("%I64d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: