hdu 5637 BestCoder Round #74 (div.2)
Transform
Accepts: 7
Submissions: 49
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
给出n个整数, 对于一个整数x, 你可以做如下的操作若干次: + 令x的二进制表示为b31b30...b0, 你可以翻转其中一个位. + 令y是给出的其中一个整数, 你可以把x变为x⊕y, 其中⊕表示位运算里面的异或操作. 现在有若干整数对(S,T), 对于每对整数你需要找出从S变成T的最小操作次数.
输入描述
输入包含多组数据. 第一行有一个整数T (T≤20), 表示测试数据组数. 对于每组数据: 第一行包含两个整数n和m (1≤n≤15,1≤m≤105), 表示给出整数的数目和询问的数目. 接下来一行包含n个用空格分隔的整数a1,a2,...,an (1≤ai≤105). 接下来m行, 每行包含两个整数si和ti (1≤si,ti≤105), 代表一组询问.
输出描述
对于每组数据, 输出一个整数S=(i=1∑mi⋅zi) mod (109+7), 其中zi是第i次询问的答案.
输入样例
1 3 3 1 2 3 3 4 1 2 3 9
输出样例
10
Hint
3→4 (2次操作): 3→7→4 1→2 (1次操作): 1⊕3=2 3→9 (2次操作): 3→1→9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | /* hdu 5637 给你n个数,然后对于x有两种操作: 1.改变x二进制中的一位,即1->0 or 0->1 2.将x与n个数中的t异或得到 x^t 求最后得到y的最小操作数 最开始想到求出x^y,但是不知道怎么处理。如果每个询问都进行一次搜索的话感觉 会TLE,为什么就没想到预处理出来- -! 正解: 先把上面两种操作得到所有情况求出来,然后从x->y也就是异或上(x^y),而这个值 的最小步数已经处理出来,直接进行O(1)的查询即可 hhh-2016-03-06 12:12:08 */ #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <queue> #include <algorithm> using namespace std; typedef long long ll; #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) const int maxn=100500; const int MOD = 1e9+7; int a[maxn]; int step[maxn<<2]; int tp[maxn<<2]; int y,n; int ans ; void bfs() { memset (step,-1, sizeof (step)); int star = 0,tail = 0; tp[0] = 0,step[0] = 0; while (star <= tail) { int cur = tp[star]; for ( int i =1; i <= n;i++) { int t = cur^a[i]; if (step[t] != -1) continue ; tp[++tail] = t; step[t] = step[cur]+1; } for ( int i =0;i <= 17;i++) { int t = cur^(1<<i); if (step[t] != -1) continue ; tp[++tail] = t; step[t] = step[cur]+1; } star++; } return ; } int main() { int t,q; scanf ( "%d" ,&t); while (t--) { scanf ( "%d%d" ,&n,&q); for ( int i =1; i <= n; i++) { scanf ( "%d" ,&a[i]); } bfs(); int x,y; ll sum = 0; for ( int i = 1;i <= q;i++) { scanf ( "%d%d" ,&x,&y); int ans = step[x^y]; sum = (sum+(ll)(i*ans)%MOD)%MOD; } printf ( "%I64d\n" ,sum%MOD); } return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步