zoukankan      html  css  js  c++  java
  • [NOI2015]寿司晚宴

    题目描述

    思路很妙啊。

    开始还在想各种奇奇怪怪的容斥,却发现无从下手。

    看到这种与质因子有关的题我们应该自然想到小于(sqrt n)的质因子应该不多。实际上确实不多,只有8个。于是我们就可以状压了。

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define N 505
    
    using namespace std;
    inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
    
    int n,mod;
    bool vis[30];
    int p[30];
    
    void pre(int n) {
    	for(int i=2;i<=n;i++) {
    		if(!vis[i]) p[++p[0]]=i;
    		for(int j=1;j<=p[0]&&i*p[j]<=n;j++) {
    			vis[i*p[j]]=1;
    			if(i%p[j]==0) break;
    		}
    	}
    }
    
    int st[N][1<<8];
    int sta[N];
    ll f[1<<8][1<<8],g[1<<8][1<<8],tem[1<<8][1<<8];
    int Mod(int a) {return a<0?a+mod:(a<mod?a:a-mod);}
    ll pw2[N];
    
    int main() {
    	pre(20);
    	n=Get(),mod=Get();
    	pw2[0]=1;
    	for(int i=1;i<=n;i++) pw2[i]=(pw2[i-1]<<1)%mod;
    	for(int i=2;i<=n;i++) {
    		int now=i;
    		for(int j=1;j<=p[0];j++) {
    			if(now%p[j]==0) sta[i]|=1<<j-1;
    			while(now%p[j]==0) now/=p[j];
    		}
    		st[now][sta[i]]++;
    	}
    	f[0][0]=1;
    	for(int i=1;i<=n;i++) {
    		if(i==1) {
    			for(int now=0;now<1<<8;now++) {
    				if(!st[i][now]) continue ;
    				memcpy(g,f,sizeof(g));
    				for(int s=0;s<1<<8;s++) {
    					for(int t=0;t<1<<8;t++) {
    						if(!(now&s)) g[s][t|now]=(g[s][t|now]+f[s][t]*(pw2[st[i][now]]-1))%mod;
    						if(!(now&t)) g[s|now][t]=(g[s|now][t]+f[s][t]*(pw2[st[i][now]]-1))%mod;
    					}
    				}
    				memcpy(f,g,sizeof(f));
    			}
    		} else {
    			memcpy(tem,f,sizeof(tem));
    			memcpy(g,f,sizeof(g));
    			for(int now=0;now<1<<8;now++) {
    				if(!st[i][now]) continue ;
    				memcpy(g,f,sizeof(g));
    				for(int s=0;s<1<<8;s++) {
    					for(int t=0;t<1<<8;t++) {
    						if(!(now&s)) g[s][t|now]=(g[s][t|now]+f[s][t]*(pw2[st[i][now]]-1))%mod;
    					}
    				}
    				memcpy(f,g,sizeof(f));
    			}
    			memcpy(f,tem,sizeof(f));
    			
    			memcpy(tem,g,sizeof(g));
    			for(int s=0;s<1<<8;s++)
    				for(int t=0;t<1<<8;t++)
    					tem[s][t]=Mod(tem[s][t]-f[s][t]);
    			for(int now=0;now<1<<8;now++) {
    				if(!st[i][now]) continue ;
    				memcpy(g,f,sizeof(g));
    				for(int s=0;s<1<<8;s++) {
    					for(int t=0;t<1<<8;t++) {
    						if(!(now&t)) g[s|now][t]=(g[s|now][t]+f[s][t]*(pw2[st[i][now]]-1))%mod;
    					}
    				}
    				memcpy(f,g,sizeof(f));
    			}
    			for(int s=0;s<1<<8;s++)
    				for(int t=0;t<1<<8;t++)
    					f[s][t]=Mod(f[s][t]+tem[s][t]);
    		}
    	}
    	int ans=0;
    	for(int s=0;s<1<<8;s++)
    		for(int t=0;t<1<<8;t++)
    			ans=Mod(ans+f[s][t]);
    	cout<<ans;
    	return 0;
    }
    
    
  • 相关阅读:
    python面向对象之类,对象
    面向对象简介
    序列化模块
    sys模块简单使用
    day26作业
    day22
    day21作业
    day21
    day20作业
    day20
  • 原文地址:https://www.cnblogs.com/hchhch233/p/10434316.html
Copyright © 2011-2022 走看看