zoukankan      html  css  js  c++  java
  • LOJ #2131. 「NOI2015」寿司晚宴

    <sqrt(500)的质数只有8个
    直接状压
    剩下的大质数相同的一起dp就行了。

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 505;
    const int S = 256;
    const int p[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
    int mp[MAXN], cur, n, f[S][S], g[2][S][S], mod;
    vector<int>vec[MAXN];
    
    int main () {
    	scanf("%d%d", &n, &mod);
    	for(int i = 2; i <= n; ++i) {
    		int s = 0, tmp = i;
    		for(int j = 0; j < 8; ++j) {
    			if(tmp % p[j] == 0) {
    				while(tmp % p[j] == 0) tmp /= p[j];
    				s |= 1<<j;
    			}
    		}
    		vec[tmp==1?++cur:mp[tmp]?mp[tmp]:mp[tmp]=++cur].push_back(s);
    	}
    	f[0][0] = 1;
    	for(int i = 1; i <= cur; ++i) {
    		for(int j = 0; j < S; ++j)
    			for(int k = 0; k < S; ++k)
    				g[0][j][k] = g[1][j][k] = f[j][k];
    		for(int o = vec[i].size()-1; ~o; --o)
    			for(int j = S-1; ~j; --j)
    				for(int k = S-1; ~k; --k)
    					if((vec[i][o]&k) == 0) {
    						(g[0][j|vec[i][o]][k] += g[0][j][k]) %= mod;
    						
    						(g[1][k][j|vec[i][o]] += g[1][k][j]) %= mod;
    					}
    		for(int j = 0; j < S; ++j)
    			for(int k = 0; k < S; ++k)
    				f[j][k] = (g[0][j][k] + g[1][j][k] - f[j][k]) % mod;
    	}
    	int ans = 0;
    	for(int j = 0; j < S; ++j)
    		for(int k = 0; k < S; ++k)
    			(ans += f[j][k]) %= mod;
    	printf("%d
    ", (ans + mod) % mod);
    }
    
  • 相关阅读:
    虚拟化技术
    软件产业的知识经济 (蔡学墉)
    关于内存对齐
    Reverse Engineering
    [转]今天的操作系统 
    BasicBIOS & CMOS
    [bbk5355]第18集 Chapter 08 Handling Exceptions(01)
    [bbk1452]第1集 在Apache中使用SSL
    Linux>User Manager
    如何更新linux系统时间
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039249.html
Copyright © 2011-2022 走看看