HDU 4610(数论+枚举状态)
来源:互联网 发布:淘宝店铺引流工具 编辑:程序博客网 时间:2024/05/20 09:44
若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是不是偶数即可
#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 2000005struct node{ int a,b,p,st;//数,个数,分值,状态}num[1005];struct Ys//约数 { int num,len; int ys[N]; int cnt[N]; }temp; int n,k;int np[4];int isprime[N];int prime[N],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 4610(数论+枚举状态)
- hdu 5207(数论+枚举)
- hdu 5750 Dertouzos(数论:质数枚举)
- hdu 5812 Distance 数论+思维枚举
- hdu 4033 状态压缩枚举
- hdu 2099 整除的尾数(枚举数论)
- hdu 5019 Revenge of GCD(数论,枚举)
- hdu 4309(最大流+枚举状态)
- hdu 4433 locker(动态规划:枚举状态)
- HDU 5339 Untitled (状态压缩枚举)
- HDU-4462(状态压缩,枚举)
- hdu 3935 -枚举+位运算表示状态和状态转移
- UVA 10976 数论 枚举
- hdu 4628 Pieces (状态压缩+二进制枚举+dp)
- HDU 4462Scaring the Birds(枚举所有状态)
- HDU 4309 Seikimatsu Occult Tonneru(网络流+枚举状态)
- HDU 4403 A very hard Aoshu problem (状态压缩+枚举)
- HDU 1882 Strange Billboard 状态压缩+简单位运算+枚举~
- jQuery函数学习
- DataGridview 动态绑定Combox
- 开放windows服务器端口-----以打开端口8080为例
- 封装变化注意事项
- Hibernate HQL查询
- HDU 4610(数论+枚举状态)
- Android多线程任务优化1:探讨AsyncTask的缺陷
- Android自定义Switch控件
- vector -- STL中容器的常用函数
- HorizontalScrollView实现画廊
- row_number OVER 与 max keep 对比
- 查询Mysql状态
- 如何解决oracle数据库中“记录被另一个用户锁住”的问题
- CentOS6平台编译安装MPEG4IP