题目链接:
Transform
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 685 Accepted Submission(s): 244
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 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 nintegers 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
题意:
两种操作,一种是是x^y,y是ai,还有一种是改变x的二进制位中的一位,相当于异或一个2的j次方(j=0,1,2,3,4...);
问s到t最少需要多少次,ans=sigama(i*zi)mod(1e9+7);
思路:
啊啊啊啊啊,自己又是不知道该怎么做,最后看了给的题解说只跟s^t有关才反应过来;这跟异或运算的性质有关;
s^x^y^z^w^...^q=t;假设这是最少的流程,等价于0^x^y^z^w..^q=s^t;就是0到s^t的最少次操作;然后用bfs把所有<=1e5都找出来;
异或运算真神奇;不过我不会.....啊啊啊啊;
AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n,m,l,r,a[100],num[300010],flag[300010]; const int mod=1e9+7; queue<int>qu; int bfs() { memset(flag,0,sizeof(flag)); for(int i=1;i<=2e5;i*=2) { a[n++]=i; } qu.push(0); num[0]=0; flag[0]=1; while(!qu.empty()) { int top=qu.front(); qu.pop(); for(int i=0;i<n;i++) { if(!flag[a[i]^top]) { qu.push(a[i]^top); num[a[i]^top]=num[top]+1; flag[a[i]^top]=1; } } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } bfs(); ll ans=0; for(int i=1;i<=m;i++) { scanf("%d%d",&l,&r); // cout<<num[l^r]<<" "<<i ans+=(ll)(num[l^r]*i); ans%=mod; } cout<<ans<<"\n"; } return 0; }