HDU 4610(数论+枚举状态)
2013-09-23 16:28
363 查看
若x=a0^p0*a1^p1*……*ai^pi(a0,a1……,ai是不同的素数)
对于条件3:因子和=(a0^0+a0^1+……+a0^p0)*(a1^0+a1^1+……+a1^p1)*……
如果是素数,显然质因子个位要为1,并且(a0^(p0+1)-1)/(a0-1)为素数
对于条件4:设因子积为a0^q0*a1^q1*……*ai^qi(a0,a1……,ai是不同的素数)
则有qi=(pi*pi+1)/2*(p0+1)*(p1+1)……(p(i-1)+1),判断所有的qi是不是偶数即可
对于条件3:因子和=(a0^0+a0^1+……+a0^p0)*(a1^0+a1^1+……+a1^p1)*……
如果是素数,显然质因子个位要为1,并且(a0^(p0+1)-1)/(a0-1)为素数
对于条件4:设因子积为a0^q0*a1^q1*……*ai^qi(a0,a1……,ai是不同的素数)
则有qi=(pi*pi+1)/2*(p0+1)*(p1+1)……(p(i-1)+1),判断所有的qi是不是偶数即可
#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <map> #include <vector> #include <cmath> #include <stack> #include <queue> #include <cstdlib> #include <algorithm> #include <fstream> #include <ctime> #include <set> using namespace std; #define inf 0x3f3f3f3f #define ll long long #define N 2000005 struct node { int a,b,p,st;//数,个数,分值,状态 }num[1005]; struct Ys//约数 { int num,len; int ys ; int cnt ; }temp; int n,k; int np[4]; int isprime ; int prime ,sum; bool cmp(node a,node b) { return a.p>b.p; } void initisprime()//判断素数 { int i,j; for(i=2;i<N;i++)isprime[i]=1; for(i=2;i<N;i++) { for(j=2;i*j<N;j++) isprime[i*j]=0; } } void initprime()//筛选素数 { int i,j,flag; prime[0]=2; sum=1; for(i=3;i<N;i++) { flag=1; for(j=0;j<sum&&prime[j]*prime[j]<=i;j++) { if(i%prime[j]==0) { flag=0;break; } } if(flag)prime[sum++]=i; } } void fj(int num)//分解质因数 { temp.num=num; temp.len=0; int i; for(i=0;i<sum&&prime[i]*prime[i]<=num;i++) { if(num%prime[i]==0) { temp.ys[temp.len]=prime[i]; temp.cnt[temp.len]=1; num/=prime[i]; while(num%prime[i]==0)temp.cnt[temp.len]++,num/=prime[i]; temp.len++; } } if(num!=1) { temp.ys[temp.len]=num; temp.cnt[temp.len]=1; temp.len++; } } ll pm(ll x,ll y) { ll ret=1; while(y--)ret*=x; return ret; } int getp(int x,int mm) { int ret=0,cntd=1,sumd=0,sumj,i,j,flag,rst=0; if(isprime[x])rst|=1,ret++; //第一个条件 fj(x); if(temp.len==1&&isprime[temp.cnt[0]+1])rst|=2,ret++; //第二个条件 if(temp.len==1&&isprime[(pm(temp.ys[0],temp.cnt[0]+1)-1)/(temp.ys[0]-1)])rst|=4,ret++; //第三个条件 flag=1; for(i=0;i<temp.len;i++) { if(!flag)break; sumj=(temp.cnt[i]+1)*temp.cnt[i]/2; if(sumj%2==0)continue; for(j=0;j<temp.len;j++) { if(i!=j) { if((temp.cnt[j]+1)%2==0)break; } } if(j==temp.len)flag=0; } if(flag)rst|=8,ret++; //第四个条件 num[mm].st=rst; return ret; } int main() { initisprime(); initprime(); int t,i,ans,j,temp,re,ti,tt; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&k); for(i=0;i<n;i++)scanf("%d%d",&num[i].a,&num[i].b); for(i=0;i<4;i++)scanf("%d",&np[i]); for(i=0;i<n;i++)num[i].p=getp(num[i].a,i); printf("%d",num[0].p); for(i=1;i<n;i++)printf(" %d",num[i].p); printf("\n"); sort(num,num+n,cmp); ans=-inf; for(i=0;i<16;i++) { temp=0; tt=0; re=k; for(j=0;j<n;j++) { if((num[j].st&i)==0) { if(re==0)break; tt|=num[j].st; if(re>=num[j].b) { temp+=num[j].p*num[j].b; re-=num[j].b; } else { temp+=num[j].p*re; re=0; } if(re==0)break; } } for(j=0;j<4;j++) { if((tt&(1<<j))==0)temp+=np[j]; } if(re==0)ans=max(ans,temp); } printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu 4433 locker(动态规划:枚举状态)
- HDU 4569 Special equations(枚举+数论)(2013 ACM-ICPC长沙赛区全国邀请赛)
- hdu 3935 -枚举+位运算表示状态和状态转移
- HDU 5339 Untitled (状态压缩枚举)
- hdu 5207(数论+枚举)
- HDU 4309 Seikimatsu Occult Tonneru(最大流SAP+状态压缩枚举)
- hdu 5019 Revenge of GCD(数论,枚举)
- hdu 5750 Dertouzos(数论:质数枚举)
- HDU 4462Scaring the Birds(枚举所有状态)
- hdu 2099 整除的尾数(枚举数论)
- HDU 4610 Cards (合数分解,枚举)
- hdu 4628 Pieces (状态压缩+二进制枚举+dp)
- HDU 1043 Eight (经典八数码问题,BFS+状态枚举+伪哈希)
- hdu 4309(最大流+枚举状态)
- HDU-4462(状态压缩,枚举)
- hdu 2489 最小生成树状态压缩枚举
- HDU 5025Saving Tang Monk BFS + 二进制枚举状态
- HDU 4462Scaring the Birds(枚举所有状态)
- hdu 4309(最大流+枚举状态)
- HDU-4462 Scaring the Birds 状态压缩枚举