zoukankan      html  css  js  c++  java
  • 「NOI2015」寿司晚宴 解题报告

    「NOI2015」寿司晚宴

    这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了..

    首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好。

    然后发现有个重要的事情是后面每个质因子(x)做统计的时候都是独立的,那么单独做就好了

    显然要压两个人的前面质因子集合(f_{i,j})代表两个人分别是(i,j)集合的答案,然后一块一块的加后面的质因子就好

    加每一块时,我们显然需要处理谁选择了这一块或者都没选,再搞个(dp_{0/1,i,j})钦定一下谁选,随便转移一下就好了


    Code:

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    template <class T>
    void read(T &x)
    {
    	x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    }
    const int N=510;
    const int pri[9]={0,2,3,5,7,11,13,17,19};
    int n,m,p,dp[2][1<<8][1<<8],f[1<<8][1<<8];
    inline int add(int a,int b){return a+b>=p?a+b-p:a+b;}
    inline int mul(int a,int b){return 1ll*a*b%p;}
    struct num
    {
    	int s,pri;
    	bool friend operator <(num a,num b){return a.pri<b.pri;}
    }yuu[N];
    int main()
    {
    	read(n),read(p);
    	for(int i=2;i<=n;i++)
    	{
    		yuu[i].pri=i;
    		for(int j=1;j<=8;j++)
    			if(i%pri[j]==0)
    			{
    				yuu[i].s|=1<<j-1;
    				while(yuu[i].pri%pri[j]==0) yuu[i].pri/=pri[j];
    			}
    	}
    	std::sort(yuu+2,yuu+n+1);
    	f[0][0]=1;int U=(1<<8)-1;
    	for(int i=2;i<=n;i++)
    	{
    		if(yuu[i].pri!=yuu[i-1].pri||yuu[i].pri==1)
    		{
    			memcpy(dp[0],f,sizeof f);
    			memcpy(dp[1],f,sizeof f);
    		}
    		int sta=yuu[i].s;
    		for(int s=U;~s;s--)
    			for(int t=U;~t;t--)
    				if(!(s&t))
    				{
    					if(!(t&sta)) dp[0][s|sta][t]=add(dp[0][s|sta][t],dp[0][s][t]);
    					if(!(s&sta)) dp[1][s][t|sta]=add(dp[1][s][t|sta],dp[1][s][t]);
    				}
    		if(yuu[i].pri!=yuu[i+1].pri||yuu[i].pri==1)
    		{
    			for(int s=0;s<=U;s++)
    				for(int t=0;t<=U;t++)
    					if(!(s&t))
    						f[s][t]=add(add(dp[0][s][t],dp[1][s][t]),p-f[s][t]);
    		}
    	}
    	int ans=0;
    	for(int s=0;s<=U;s++)
    		for(int t=0;t<=U;t++)
    			ans=add(ans,f[s][t]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    2019.3.4

  • 相关阅读:
    git代码回退
    7 用两个栈实现队列
    《Java并发编程实战》学习笔记
    226. Invert Binary Tree
    Interface与abstract类的区别
    Override和Overload的区别
    Java面向对象的三个特征与含义
    String、StringBuffer与StringBuilder的区别
    Hashcode的作用
    Object有哪些公用方法
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10472085.html
Copyright © 2011-2022 走看看