首页 > 代码库 > 编程之美初赛第二场 集合
编程之美初赛第二场 集合
题目3 : 集合
时间限制:12000ms
单点时限:6000ms
内存限制:256MB
A,B都是{1, 2, …, N}的子集;
A,B没有公共的元素;
f(A)<= f(B)。f(S)定义为S中所有元素的按位异或和。例如, f({}) = 0, f({1, 3}) = 2。
- 样例输入
1 3 100000000
- 样例输出
Case 1: 18
描述
统计满足下列条件的集合对(A, B)的数量:
因为答案可能很大,你只需要求出它除以M的余数。
输入
第一行一个整数T (1 ≤ T ≤ 10),表示数据组数。
接下来是T组输入数据,测试数据之间没有空行。
每组数据格式如下:
仅一行,2个整数N和M (1 ≤ M ≤ 108)。
输出
对每组数据,先输出“Case x: ”,然后接一个整数,表示所求的结果。
数据范围
小数据:1 ≤ N ≤ 20
大数据:1 ≤ N < 212
#include <stdio.h> #define LONG unsigned long long int f(int n,int total) { int r=0,i=0,j=0; for (i=1,j=1;j<total+1;j++,i=i<<1) { if ((n&i)!=0) { r^=j; } } //printf("f %d--%d\n",n,r); return r; } LONG mypow(int a, int n) { int i; LONG res = 1; for (i = 0; i < n; ++i) { res *= a; } return res; } int main(void) { int T=0,num=0,N,M; LONG i,j,count,upper; scanf("%d",&T); getchar(); while(num<T) { scanf("%d %d",&N,&M); count = 1; upper = mypow(2, N); //printf("upper:%ld\n",upper); for (i = 0; i < upper-1; ++i) { for (j = i+1; j < upper; ++j) { if ((i&j) == 0) { if (f(i,N)!= f(j,N)) count++; else count+=2; if (count >= M) { count -= M; } } } } printf("Case %d: count:%d\n",++num,count); } return 0; }
#include <stdio.h> #define LONG unsigned long long LONG f(LONG n,LONG total) { LONG r=0,i=0,j=0; for (i=1,j=1; j<total+1; j++,i=i<<1) { if ((n&i)!=0) { r^=j; } } //printf("f %lld--%lld\n",n,r); return r; } LONG muti_mod(LONG a,LONG b,LONG MOD)//(a*b)mod MOD { a%=MOD; b%=MOD; LONG ret=0; while (b)//fast mul { if (b&1)//a*b=a+a(b-1) { ret+=a;//ret = (ret + a)%c if (ret>=MOD) ret-=MOD; } //a*b=a*2 *b/2 b>>=1; a<<=1; if (a>=MOD) a-=MOD; } return ret; } LONG mypow(LONG a, LONG n,int flag, LONG mod) { LONG i; LONG res = a; if(flag==0) for(i=0; i<n-1; i++) res=res*a; else for(i=0; i<n-1; i++) res=muti_mod(res,a,mod); return res; } LONG jihe(LONG n, LONG mod) { LONG i=0,j=0,p,upper,k,t=0,count=0,total=0; if(n==1) return 2; for(k=2; k<=n; k++) { p=1<<(k-1); upper = mypow(2, k-1,0,mod); if((k&(k-1))!=0)//n=2^n,count=0 { for(i=0; i<upper; i++) { t=i|p; for(j=0; j<upper; j++) { if(((t&j)==0)&&(f(t,k)==f(j,k))) count++; } } count=count%mod; } //printf("k:%lld\t count:%lld\n",k,count); count=count%mod; } // (a / b) % m = ( a % (m*b)) / b total=(mypow(3,n,1,2*mod)-1)>>1; //printf("total %lld\n",total); //printf("count %lld\n",count); return (1+total+count)%mod;// } int main(void) { unsigned int T=0,num=0,N,M; LONG count; scanf("%d",&T); getchar(); while(num<T) { scanf("%d %d",&N,&M); count=jihe(N,M); printf("Case %d: count:%lld\n",++num,count); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。