标签:
小白错误总结之暴int:
题目大意:给你一系列的数字,拿出两个进行匹配,看是否是2的幂,输出总匹配数;数据范围1e9,长度1e5;
想法:匹配分为跟自己匹配和跟另一个数进行匹配,自己配就是排列n找2,n!/(n-2)!,不同直接乘。
考虑到数字相同的情况,就要考虑到压缩,排序(sort,o(n*log(n))),记录下数字大小及个数o(n),当然可以用map,本人小白,没用过不熟,处理好进行匹配。
匹配分三层,一层向前,一层跑2的幂,内条件加限制跑到最大数的二倍就够了,本人小白,没考虑太多,直接给了四倍,一层二分找另一个数是否存在,存在输出位置标,时间o(n*logn*logn),中层因为是二倍增长的所以是logn。
代码:
#include <iostream> #include <stdio.h> #include <algorithm> #include <math.h> #include <cstdio> #include <cstring> #include <string> #include <string.h> #include <vector> #include <queue> #include <map> #include <set> using namespace std; const long long inf=(int)1e12+88; const int maxn=(int)1e6+88; const int mod=1000000007; long long a[maxn]; int len[maxn]; long long mi[50]; int ch(int aa,int b,long long c) { while(aa<=b) { int mid=(aa+b)/2; if(a[mid]==c)return mid; else if(a[mid]>c)b=mid-1; else aa=mid+1; } return -1; } int main() { // freopen("1010.in", "r", stdin); // freopen("out.txt", "w", stdout); int t; int tt=0; mi[0]=1; for(int i=1; i<50; i++) mi[i]=mi[i-1]*2; cin>>t; for(int i=0; i<t; i++) len[i]=1; for(int i=0; i<t; i++) { cin>>a[i]; } sort(a,a+t); int q=0; for(int i=1; i<t; i++) { if(a[i]!=a[i-1]) a[++q]=a[i]; else { len[q]++; } } t=q+1; long long ans=0; a[t]=inf; len[t]=0; for(int i=0; i<t; i++) { for(int j=0; 4*a[t-1]>=mi[j]; j++)//开四倍,小白,不想太多; { if(mi[j]>=a[i]) { int bb=ch(0,t,mi[j]-a[i]); if(bb!=-1) { if(bb==i) ans+=((long long)len[bb])*(len[bb]-1);//炸了,修改就强转!!! else ans+=((long long)len[bb])*len[i];//上面本应比2,但这里统计两次,最后一块处理 } } } } cout<<ans/2;//统计了两遍,比2; return 0; }
最后小白总结1e5有乘就暴int,以后改用longlong,顺便写个重命名好了,int,再见;
标签:
原文地址:http://www.cnblogs.com/aishuijdemiaomiao/p/5720086.html