【NOI2019模拟2019.6.27】幻化成风(集合容斥系数,胡乱dp)
Description:
题解:
xjb乱搞题,卡死在无序了。
考虑肯定是枚举个集合划分,然后强制一个集合里的选的b一样嘛,就可以无限背包了,然后发现如果按题意说的无序的话特别难做,不妨考虑有序,即每一个a[i]都有标号,最后除以∏cnt[a[i]]\prod cnt[a[i]]∏cnt[a[i]]就好了。
先思考暴力枚举集合划分,系数是什么,系数应该是只和这个集合包含的元素有关的,不妨设f[i]f[i]f[i]表示一个i个点的集合的容斥系数,显然需要满足:
[n=1]=ef[xn]∗n![n=1]=e^{f}[x^n]*n![n=1]=ef[xn]∗n!
因为是有标号的。
写成dp式就是[n=1]=f[n]+∑i=1n−1Cn−1i−1∗f[i]∗[(n−i)=1][n=1]=f[n]+\sum_{i=1}^{n-1}C_{n-1}^{i-1}*f[i]*[(n-i)=1][n=1]=f[n]+∑i=1n−1Cn−1i−1∗f[i]∗[(n−i)=1]
归纳一下就是f[n]=(−1)n−1∗(n−1)!f[n]=(-1)^{n-1}*(n-1)!f[n]=(−1)n−1∗(n−1)!
pty给了生成函数的推法:
要使efe^fef次方的一次项系数为1(常数),>1次项系数为0,那么直接将ln(1+x)ln(1+x)ln(1+x)带进去,经过一波求导、泰勒展开可以得到同样的东西。
然后我们肯定不能暴力枚举集合划分。
注意对于一个划分我们只关心每一个集合∑a[i]\sum a[i]∑a[i]和元素个素,那么两种划分的各个集合的∑a[i]\sum a[i]∑a[i]和元素个素一样的是可以缩到一起的,这个可以用set套map实现。
这样直接dp还是会T非的,在搞完上面的之后,再把各个∑a[i]\sum a[i]∑a[i]一样的缩到一起dp,由于30分整数拆分数只有5000+,即可通过本题……
.
.
.
才怪,这个破题卡常到上天,
然后我发现前面的set套map巨慢,所以把set展开成数组,又搞了个hash值来快速比较。
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;const int N = 1e4 + 5;int n, m, a[N], b[N];
int bz[N], p[N], c[N];void sieve(int n) {fo(i, 2, n) {if(!bz[i]) p[++ p[0]] = i;for(int j = 1; i * p[j] <= n; j ++) {bz[i * p[j]] = 1;if(i % p[j] == 0) break;}}fo(i, 1, p[0]) {for(ll s = p[i]; s <= n; s *= p[i]) c[i] += n / s;}
}const int mo = 1e9 + 7;ll ksm(ll x, ll y) {ll s = 1;for(; y; y /= 2, x = x * x % mo)if(y & 1) s = s * x % mo;return s;
}
ll fac[N], nf[N];struct P {int x, y;P(int _x = 0, int _y = 0) { x = _x, y = _y;}
};bool operator < (P a, P b) {if(a.x == b.x) return a.y < b.y;return a.x < b.x;
}#define ul unsigned long long
struct D {P a[31];ul s;
};
ul a3[105];
void calc(D &a) {a.s = 0;fo(i, 1, a.a[0].x)a.s += a3[i] * a.a[i].x + a3[i + 30] * a.a[i].y;
}bool operator < (D a, D b) {return a.s < b.s;if(a.a[0].x != b.a[0].x) return a.a[0].x < b.a[0].x;if(a.a[1].x != b.a[1].x) return a.a[1].x < b.a[1].x;if(a.a[2].x != b.a[2].x) return a.a[2].x < b.a[2].x;fd(j, a.a[0].x, 3) {if(a.a[j].x < b.a[j].x) return 1;if(a.a[j].x > b.a[j].x) return 0;if(a.a[j].y < b.a[j].y) return 1;if(a.a[j].y > b.a[j].y) return 0;}return 0;
}map<D, int> :: iterator it;
map<D, int> d[2]; int o;
#define fi first
#define se secondmap<multiset<int>, int> t;
map<multiset<int>, int> :: iterator it3;
multiset<int> :: iterator it4;int f[N];ll ans;D s;int main() {freopen("count.in", "r", stdin);freopen("count.out", "w", stdout);a3[0] = 1; fo(i, 1, 100) a3[i] = a3[i - 1] * 7;scanf("%d %d", &n, &m);sieve(n);fo(i, 1, m) scanf("%d", &a[i]);sort(a + 1, a + m + 1);int m0 = m; m = 0;fo(i, 1, m0) {if(!m || a[i] != a[m])a[++ m] = a[i], b[m] = 1; elseb[m] ++;}fac[0] = 1; fo(i, 1, 30) fac[i] = fac[i - 1] * i % mo;nf[30] = ksm(fac[30], mo - 2); fd(i, 30, 1) nf[i - 1] = nf[i] * i % mo;d[o][s] = 1;fo(i, 1, m) {fo(tim, 1, b[i]) {d[!o].clear();for(it = d[o].begin(); it != d[o].end(); it ++) {s = (*it).fi;fo(j, 1, s.a[0].x) {D g = s;g.a[j].x += a[i]; g.a[j].y ++;sort(g.a + 1, g.a + g.a[0].x + 1);calc(g);d[!o][g] = (d[!o][g] + (*it).se) % mo;}s.a[++ s.a[0].x].x = a[i]; s.a[s.a[0].x].y = 1;sort(s.a + 1, s.a + s.a[0].x + 1);calc(s);d[!o][s] = (d[!o][s] + (*it).se) % mo;}o = !o;
// fprintf(stderr, "%d\n", d[o].size());}}for(it = d[o].begin(); it != d[o].end(); it ++) {s = (*it).fi; ll g = (*it).se;multiset<int> s2; s2.clear();fo(i, 1, s.a[0].x) {s2.insert(s.a[i].x);g = g * (mo - 1) % mo * fac[s.a[i].y - 1] % mo;}t[s2] = (t[s2] + g) % mo;}for(it3 = t.begin(); it3 != t.end(); it3 ++) {memset(f, 0, sizeof f);f[0] = 1;multiset<int> s = (*it3).fi;for(it4 = s.begin(); it4 != s.end(); it4 ++) {int x = (*it4);fo(j, x, c[1]) f[j] = (f[j] + f[j - x]) >= mo ? (f[j] + f[j - x] - mo) : (f[j] + f[j - x]);}ll sum = 1;fo(i, 1, p[0]) sum = sum * f[c[i]] % mo;ans = (ans + sum * (*it3).se) % mo;}fo(i, 1, m) ans = ans * nf[b[i]] % mo;if(m0 & 1) ans = (mo - ans) % mo;pp("%lld\n", ans);
}
【NOI2019模拟2019.6.27】幻化成风(集合容斥系数,胡乱dp)相关推荐
- 20200515省选模拟赛B、幻化成风(毒瘤容斥题+构造容斥系数+生成函数+hash状压DP+Trie树优化背包)
题解 花了一上午+一中午终于把这道题A了 首先,我们要求的是bi互不相同的合法方案数 我们可以枚举一个a的集合S,来强制里面的b全部都相同,然后其它的随便放 由于这个题的n的约数非常多,我们可以把它质 ...
- 【NOI2019模拟2019.7.4】朝夕相处 (动态规划+BM)
Description: 题解: 这种东西肯定是burnside引理: \(\sum置换后不动点数 \over |置换数|\) 一般来说,是枚举置换\(i\),则\(对所有x,满足a[x+i]=a[i ...
- 【NOI2019模拟2019.7.1】为了部落 (生成森林计数,动态规划)
Description: \(1<=n<=1e9,1<=m,k<=100\) 模数不是质数. 题解: 先选m个点,最后答案乘上\(C_{n}^m\). 不妨枚举m个点的度数和D ...
- 省选模拟 幻化成风(容斥原理,状压DP)
首先这个aia_iai相同的时候无序的要求,直接按有序求答案,然后除aia_iai相同的个数的阶乘即可,因为我们的bbb两两不同. 有序的答案要两两不同,我们考虑容斥哪些相同,可以想到的较高效容斥 ...
- 日常(更新至2019.6.27)
离别在六月 --虽是这么说,我才大一即将结束 第二学期因为自己积极的学(qiao)算(ke)法,微积分和物理面临毁灭性打击orz 周日开始进入考试周,而我还在对着物理发愁 微积分还算是人能看得懂的 学 ...
- 【Science】破解密码“AlphaGo”诞生,训练Gan破解27%LinkedIn测试集密码
本文讲的是破解密码"AlphaGo"诞生,训练Gan破解27%LinkedIn测试集密码,一项新的研究旨在使用生成对抗网络(GAN) 来加快密码破解的速度.斯蒂文斯理工学院的研究人 ...
- AI英特尔杯公开课:2019.06.27在线直播《研究生人工智能创新大赛—AI赋能,创新引领》课堂笔记和感悟(二)
AI英特尔杯公开课:2019.06.27在线直播<研究生人工智能创新大赛-AI赋能,创新引领>课堂笔记和感悟(二) 导读 讲解总体不错,知识点比较基础,适合入门,各种主流框架都有 ...
- AI英特尔杯公开课:2019.06.27在线直播《研究生人工智能创新大赛—AI赋能,创新引领》课堂笔记和感悟(一)
AI英特尔杯公开课:2019.06.27在线直播<研究生人工智能创新大赛-AI赋能,创新引领>课堂笔记和感悟(一) 导读 讲解总体不错,知识点比较基础,适合入门,各种主流框架都有 ...
- 18天精读掌握《费曼物理学讲义卷一》 第11天 2019/6/27
18天精读掌握<费曼物理学讲义卷一> 第11天 2019/6/27 1. 18日掌握<费曼物理学讲义>卷一计划概览 2. 今日学习成果 3. 今日时间表 4.Atimelogg ...
最新文章
- fedora java 开发环境_Linux(Fedora 14)下 java开发环境配置 ——jdk的安装与配置
- JavaScript错误:Maximum call stack size exceeded错误
- Django入门项目实践(中)
- 对Spring创建对象的思考
- Android入门逆引手册 - 12 评分条(RatingBar)的使用
- 电商海报模板|psd分层海报素材轻松教你凸显你的主体产品!
- windows安装vnm
- Codeforces Round #468 (Div. 2): E. Game with String
- 黑马程序员传智播客python 协程greenlet gevent学习笔记
- 我的时时在线电脑(千脑)
- Max Script|控制器-位置约束_path
- 解决cadence导入网编Symbol ‘SOD_123‘ used by RefDes D31 for device ‘XXXXX‘ not found的问题
- 线程----code
- 十大重要IT公司排名 -2009
- 《 浅 谈 C T F 》
- MT1308芯片原厂
- 创业者两大特征:喜欢折腾与坚持不懈
- python seaborn学习笔记
- 个人怎么做微信小程序?
- python mongodb分页查询_python数据库分页查询语句