HDU 5637 Transform 最短路
2016-03-05 22:32
225 查看
Transform
题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=5637Description
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
13 3
1 2 3
3 4
1 2
3 9
Sample Output
10Hint
题意
给出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); } }
相关文章推荐
- Linux第二周学习总结——操作系统是如何工作的
- 重写js alert
- 21分钟 MySQL 入门教程
- AWK 简明教程
- 利用泛型实现一个简单的android orm小例子
- leetcode:Single Number II 【Java】
- JavaBean和Servlet的区别
- 27. Remove Element
- 文件加密2——基础版(限文本)
- 关于blob,clob,varchar2
- windows客户端开发--如何修复输入法提示框位置不正确
- Android开发搭环境步骤, ADT, JDK, SDK, NDK, Eclipse, CDT
- vivo软件开发笔试编程题:
- windows客户端开发--如何修复输入法提示框位置不正确
- php显示判断数组是不是带下标的二维数组
- 项目开发环境搭建手记(5.Jenkins搭建)
- Nokia 5110 LCD资料
- 版本控制SVN的使用笔记
- Python Select 解析
- noj1044(并查集)