【2015广东工业大学新生赛A】【排序 二进制数位思想】GG和女神 数字按照数值排序后取了多少个数

来源:互联网 发布:python数据分析书籍 编辑:程序博客网 时间:2024/05/22 08:10
#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}const int N=1e6+10,M=0,Z=1e9+7,ms63=1061109567;int casenum,casei;int n,m,x;LL a[N];int main(){scanf("%d",&casenum);for(casei=1;casei<=casenum;++casei){scanf("%d%d",&n,&m);for(int i=1;i<=n;++i){scanf("%lld",&a[i]);a[i]<<=1;}for(int i=1;i<=m;++i){scanf("%d",&x);a[x]|=1;}sort(a+1,a+n+1);int ans=0;for(int i=1;i<=m;++i){scanf("%d",&x);ans+=a[x]&1;}printf("%d\n",ans);}return 0;}/*【题意】有n(1e6)个数,第i个数的数值为a[i](a[i]<=1e17),我们选取了其中的k(1<=k<=n)个。然而这些数被经过了数值从小到大的排序,然后再告诉你k个数,问你这k个数中,有多少个数是被我们选过的。【类型】排序 二进制数位思想【分析】我们可以利用二进制数值转化思想。把每个数左移一位,不会改变这些数的大小关系和排序结果。如果一个数之前选取,那就把最后一位|=1。那对于后来得知的k个数,我们看其对应的数的最后一位是不是1,就知道这个数之前是否选过。然后这题就做完了哦,常数超小,空间超小哦!【时间复杂度&&优化】O(nlogn)*/

0 0
原创粉丝点击