zoukankan      html  css  js  c++  java
  • BZOJ 4197: [Noi2015]寿司晚宴

    状压<=sqrt(n)的所有质因数

    对所有数分解质因数,大于sqrt(n)的质因数最多出现一次

    包含相同大于sqrt(n)的质因数的数应该都归属于同一个人

    按大于sqrt(n)的质因数排序

    F[X][Y]表示两个人小于sqrt(n)的质因数的选取情况

    G[0/1][X][Y]用于转移包含相同的大于sqrt(n)的质因子的数

    精妙之处在于用状压然后分类避免了质因数之间相互影响的情况

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,mod,F[305][305],G[2][305][305];
    int prime[8]={2,3,5,7,11,13,17,19};
    struct node{
    	int S,val;
    }E[505];
    bool cmp(node a,node b){
    	return a.val<b.val;
    }
    int main(){
    	scanf("%d%d",&n,&mod);
    	for (int i=2; i<=n; i++){
    		int x=i;
    		for (int j=0; j<8; j++)
    			if (x%prime[j]==0){
    				E[i-1].S|=1<<j;
    				while (x%prime[j]==0) x/=prime[j];
    			}
    		E[i-1].val=x;
    	}
    	n--;
    	sort(E+1,E+n+1,cmp);
    	F[0][0]=1;
    	int N=8;
    	for (int i=1; i<=n; i++){
    		if (E[i].val==1 || E[i].val!=E[i-1].val){
    			for (int X=0; X<(1<<N); X++)
    				for (int Y=0; Y<(1<<N); Y++) 
    					G[0][X][Y]=G[1][X][Y]=F[X][Y];
    		}
    		for (int X=(1<<N)-1; X>=0; X--)
    			for (int Y=(1<<N)-1; Y>=0; Y--)
    				if (!(X&Y)){
    					if (!(E[i].S&Y)) (G[0][X|E[i].S][Y]+=G[0][X][Y])%=mod;
    					if (!(E[i].S&X)) (G[1][X][Y|E[i].S]+=G[1][X][Y])%=mod;
    				}
    		if (E[i].val==1 || E[i].val!=E[i+1].val){
    			for (int X=0; X<(1<<N); X++)
    				for (int Y=0; Y<(1<<N); Y++)
    					if (!(X&Y)) F[X][Y]=((G[0][X][Y]+G[1][X][Y]-F[X][Y])%mod+mod)%mod;
    		}
    	}
    	int ans=0;
    	for (int X=0; X<(1<<N); X++)
    		for (int Y=0; Y<(1<<N); Y++)
    			if (!(X&Y)) (ans+=F[X][Y])%=mod;
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    C#获取本地IP地址
    C#中将字符串转换成数值
    JavaScript实现基于对象的双端队列
    Java网络编程
    JavaScript实现基于对象的队列
    JavaScript实现基于对象的栈
    JavaScript实现基于数组的栈
    发送短信按钮倒计时案例
    JavaScript动态显示时间
    html
  • 原文地址:https://www.cnblogs.com/silenty/p/9873113.html
Copyright © 2011-2022 走看看