HDU 5637 Transform 最短路

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);
    }
}
    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/5246135.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞