这是昨晚队友跟我说的题,不知道当时是什么玄幻的事件发生了,,我看成了两两相乘的XOR 纠结了好长时间间 不知道该怎么办
今天早上看了下这道题,发现是两两相加的XOR 然后就想了想昨晚的思路 发现可做
对于 XOR 在我的记忆中 ,大部分的都是拆成数位来做
那么这题 。。。。 其实也是类似的
拆成数位。有两种拆法 将数据拆成数位和将答案拆成数位(其实就是考虑答案的每一位)
想了想将数据拆成数位··········
没法单独考虑每一位的‘功’
那就将考虑答案的每一位了
最好考虑的是第一位了
只有1+0 才能得到 1 也就是数数 a b数组 1 和 0 的个数了,
第2位呢? 如果两个数组前两位的值相加不小于2^1 并且小于2^2就行了。。他的第2位不就是1了么??
以此类推,,,每一位数1的个数。。。
开始写代码
wa
想了想原因 试了一下1 1 3 3 这组数据发现答案是4 又想了想,,
在考虑第2位,,2=<ai+bi<4 || 6=<ai+bi<8 才是对的,,,
然后以此类推,
又错了,,,怎么搞的?
确认算法没错之后,,看了看输入输出,,
好久没做题
1 #include <iostream> 2 #include <cstdio> 3 #include <string.h> 4 #include <algorithm> 5 6 #define cl(a,b) memset(a,b,sizeof(a)) 7 #define ll long long 8 #define ull unsigned long long 9 using namespace std; 10 11 #define maxn 200005 12 13 ull aa[maxn],bb[maxn]; 14 ull taa[maxn],tbb[maxn]; 15 ull cc[64],be[64],en[64]; 16 int n; 17 18 void initcc() 19 { 20 cl(cc,0); 21 cc[0]=1; 22 be[0]=1; 23 en[0]=2; 24 for(int i=1;i<=62;i++) 25 { 26 cc[i]=cc[i-1]*2+1; 27 be[i]=be[i-1]*2; 28 en[i]=en[i-1]*2; 29 } 30 // for(int i=0;i<62;i++)printf("%I64d %I64d %I64d\n",cc[i],be[i],en[i]); 31 } 32 33 int main() 34 { 35 initcc(); 36 int tt,ii; 37 cin>>tt; 38 ii=0; 39 while(tt--) 40 { 41 scanf("%d",&n); 42 int i,j,k; 43 for(i=0;i<n;i++)scanf("%llu",&aa[i]); 44 for(i=0;i<n;i++)scanf("%llu",&bb[i]); 45 ull res=0,bitc; 46 int s1,s2,e1,e2; 47 for(k=0;k<62;k++) 48 { 49 for(i=0;i<n;i++) 50 { 51 taa[i]=aa[i]&cc[k]; 52 tbb[i]=bb[i]&cc[k]; 53 } 54 sort(taa,taa+n); 55 sort(tbb,tbb+n); 56 s1=n-1;e1=n-1;bitc=0; 57 s2=n-1;e2=n-1; 58 for(i=0;i<n;i++) 59 { 60 while(s1>=0&&tbb[s1]+taa[i]>=be[k])s1--; 61 while(e1>=0&&tbb[e1]+taa[i]>=en[k])e1--; 62 63 while(s2>=0&&tbb[s2]+taa[i]>=be[k]+en[k])s2--; 64 while(e2>=0&&tbb[e2]+taa[i]>=en[k+1])e2--; 65 66 bitc+=e1-s1; 67 bitc+=e2-s2; 68 } 69 70 res+=be[k]*(bitc%2); 71 } 72 printf("Case #%d: %llu\n",++ii,res); 73 } 74 return 0; 75 }
g++ 不支持 I64d???
无语了 换了输入输出
总算ac
时间: 2024-09-29 02:57:30