[CF804F]Fake bullions
Solution:
这题可以分为两个部分,
一个部分为处理出每个点最大的金条数与最小的金条数,记为 \([Min_i, Max_i]\)
第二部分为对于 \(n\) 个变量 \(x_i\in[Min_i, Max_i]\cup \mathbb {Z}\),计算选出 \(B\) 个前 \(A\) 大变量的方案数。
对于两个点 u->v
,如果有 u
的人 i
(
有金条)
与 v
的人 j
满足 \(i\equiv j(\text{mod }\gcd(S_u, S_v))\) ,那么 i
就可以给 j
假金条。
同理,对于一条路径 u->...->v
设 g
为其 \(\gcd\) ,那么只要满足 \(i \equiv j(\text{mod }g)\) ,那么 i
就可以给 j
假金条。
所以对于一个强连通分量中,有金条的人就会满足 \(i\equiv j(\text{mod } g)\) ,j
为每个点有金条的人,g
为整个强连通分量的 \(\gcd\) 。
枚举一个点有金条的人,这样就可以 \(O(\text{金条数目})\) 求出每一个强连通分量的金条拥有状态。
由竞赛图的性质,缩点后的竞赛图还是竞赛图,而且会长这个样子:
即每个点都向它后面连边,显然我们为了让金条数量最大化就是按照拓扑序依次算点的贡献,这样算出来每个强连通分量的金条数假设为 Mx
那么每个点u
拥有的金条数就是\(\frac{S_uMx}{g}\)。
接下来就考虑怎么计数,为了不算重,枚举 u
为B中最小的点,然后统计出 \(Max_u<Min_i\) 的数量 \(cnt_1\),以及 \(Max_i\geq Max_u\geq Min_i\) 的数量 \(cnt_2\),那么再枚举在 \(cnt_2\)个中选j
个,给答案加上 \({~cnt_2~\choose j}{~cnt_1~\choose B - 1 - j}\)。
#include <iostream>
#include <cstdio>
#include <set>
#include <algorithm>
#include <vector>
#define LL long long
using namespace std;
const int maxn = 5003;
const int MOD = 1e9 + 7;
vector<int> g[maxn];
vector<bool> city[maxn];
int A, B, n;
int s[maxn], fac[maxn], ifac[maxn];
void input() {
char str[(int)(2e6) + 2];
scanf("%d %d %d", &n, &A, &B);
for (int i = 1; i <= n; ++i) {
scanf("%s", str + 1);
for (int j = 1; j <= n; ++j)
if (str[j] == '1')
g[i].push_back(j);
}
for (int i = 1; i <= n; ++i) {
scanf("%d %s", &s[i], str);
city[i].resize(s[i]);
for (int j = 0; j < s[i]; ++j)
city[i][j] = str[j] - '0';
}
}
LL qpow(LL a, LL b) {
LL res(1);
while (b) {
if (b & 1) {
res = res * a % MOD;
}
a = a * a % MOD;
b >>= 1;
}
return res;
}
void init() {
fac[0] = 1;
int N = maxn - 3;
for (int i = 1; i <= N; ++i)
fac[i] = 1ll * fac[i - 1] * i % MOD;
ifac[N] = qpow(fac[N], MOD - 2);
for (int i = N - 1; i >= 0; --i)
ifac[i] = 1ll * ifac[i + 1] * (i + 1) % MOD;
}
vector<bool> colbull[maxn];
int Gcdcol[maxn], cntbull[maxn], maxbull[maxn], minbull[maxn];
int low[maxn], dfn[maxn], dfst, col[maxn], colcnt, stk[maxn], top;
void tarjan(int u) {
dfn[u] = low[u] = ++dfst;
stk[++top] = u;
for (int i = 0; i < (int)g[u].size(); ++i) {
int v= g[u][i];
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (!col[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u]) {
++colcnt;
int v;
do {
v = stk[top--];
col[v] = colcnt;
} while (u != v);
Gcdcol[colcnt] = s[u];
}
}
void solve1() {
for (int i = 1; i <= n; ++i)
if (!dfn[i])
tarjan(i);
for (int i = 1; i <= n; ++i)
Gcdcol[col[i]] = __gcd(Gcdcol[col[i]], s[i]);
for (int i = 1; i <= n; ++i) {
colbull[col[i]].resize(Gcdcol[col[i]]);
for (int j = 0; j < s[i]; ++j)
if (city[i][j] == 1) {
colbull[col[i]][j % Gcdcol[col[i]]] = 1;
}
}
vector<bool> tmp;
for (int i = colcnt; i >= 2; --i) {
int g = __gcd(Gcdcol[i], Gcdcol[i - 1]);
tmp.clear();
tmp.resize(g);
for (int j = 0; j < Gcdcol[i]; ++j)
tmp[j % g] = tmp[j % g] | colbull[i][j];
for (int j = 0; j < Gcdcol[i - 1]; ++j)
colbull[i - 1][j] = colbull[i - 1][j] | tmp[j % g];
}
for (int i = 1; i <= colcnt; ++i)
for (int j = 0; j < Gcdcol[i]; ++j)
cntbull[i] += colbull[i][j];
for (int i = 1; i <= n; ++i)
maxbull[i] = s[i] / Gcdcol[col[i]] * cntbull[col[i]];
for (int i = 1; i <= n; ++i)
for (int j = 0; j < s[i]; ++j)
minbull[i] += city[i][j];
}
LL ans;
LL combine(int n, int m) {
if (m < 0 || n < 0 || m > n) return 0;
return 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;
}
void solve2() {
for (int i = 1; i <= n; ++i) {
int cnt1 = 0, cnt2 = 0;
for (int j = 1; j <= n; ++j) {
if (i == j) continue;
if (minbull[j] > maxbull[i]) ++cnt1;
else if (maxbull[j] > maxbull[i] || (maxbull[j] == maxbull[i] and j < i)) ++cnt2;
}
if (cnt1 >= A) continue;
for (int j = min(B - 1, min(cnt2, A - 1 - cnt1)); j >= B - cnt1 - 1 && j >= 0; j--) {
ans = (1ll * ans + 1ll * combine(cnt1, B - j - 1) * combine(cnt2, j) % MOD) % MOD;
}
}
cout << ans << endl;
}
int main() {
// freopen("fake.in", "r", stdin);
// freopen("fake.out", "w", stdout);
input();
init();
solve1();
solve2();
return 0;
}
[CF804F]Fake bullions的更多相关文章
- [codeforces 804F. Fake bullions]
题目大意: 传送门. 给一个n个点的有向完全图(即任意两点有且仅有一条有向边). 每一个点上有$S_i$个人,开始时其中有些人有真金块,有些人没有金块.当时刻$i$时,若$u$到$v$有边,若$u$中 ...
- 【Codeforces】【图论】【数量】【哈密顿路径】Fake bullions (CodeForces - 804F)
题意 有n个黑帮(gang),每个黑帮有siz[i]个人,黑帮与黑帮之间有有向边,并形成了一个竞赛完全图(即去除方向后正好为一个无向完全图).在很多年前,有一些人参与了一次大型抢劫,参与抢劫的人都获得 ...
- Solution -「CF 804F」Fake bullions
\(\mathcal{Description}\) Link. 给定 \(n\) 个点的竞赛图,第 \(i\) 个点代表了 \(s_i\) 个人,每个人(0-based)可能有真金条.此后在 ...
- Fake chat script for website download
Are you searching for free fake webchat script then you are at the right place go get download your ...
- fake gucci outlet perform a couple associated with things in great trust
Based on my a lot of years of encounter within Taobao, purchase bags must go to the high reputation ...
- Zyxel Switch-How to block a fake DHCP server without enabling DHCP snooping?
How to block a fake DHCP server without enabling DHCP snooping? Scenario How to block a fake DHCP se ...
- Codeforces Round #310 (Div. 2) B. Case of Fake Numbers 水题
B. Case of Fake Numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...
- 在使用Fake framework的时候,为什么有一些函数没有生产mock呢?
在使用Visual studio 2012 的Fake framework 做单元测试的时候,你会发现有一些函数没有生产Stub 或者 Shim的版本,这可能是由于Fake的一些限制导致的,但如何知道 ...
- fake it till you become it
fake it till you become it_你泛起山川烟波里的不是我._百度空间 fake it till you become it
随机推荐
- JavaScript实现生成指定范围随机数和一个包含不重复数的随机数组
目前JavaScript里面还没有现成的方法可以实现这个简单地需求,我们就需要自己写代码了. 在js中有个函数:Math.random() 这个函数可以生成 [0,1) 的一个随机数. 我们的简单的改 ...
- dotnet ef执行报错, VS 2019发布时配置项中的Entity Framework迁移项显示不出来
VS 2019发布时配置项中的Entity Framework迁移项显示不出来 dotnet ef dbcontext list --json “无法执行,因为找不到指定的命令或文件.可能的原因包括: ...
- Archlinux笔记本安装手记
最近看着Linux Mint里一揽子乱七八糟的应用和散布各处的配置文件愈发烦躁,便想体验下大名鼎鼎的Arch,网上的帖子们把Arch Linux的安装难度描述的非常可怕,但实际上跟着Wiki一步一步来 ...
- JuniorCTF - Web - blind
题目链接 https://ctftime.org/task/7450 参考链接 https://github.com/Dvd848/CTFs/blob/master/2018_35C3_Junior/ ...
- $[WC2018]$通道(虚树,边分练习)
\([WC2018]\)通道(虚树,边分练习) 感受码题的快感 这段时间真的是忙忙忙忙忙,省选之前还是露个脸,免得以后没机会了. 但是我感觉我的博客真的没啥人看,虽然我挺想要有人看的,但是自己真的没啥 ...
- 前端经典布局:Sticky footer 布局
什么是Sticky footer布局?前端开发中大部分网站,都会把一个页面分为头部区块.内容区块.页脚区块,这也是比较.往往底部都要求能固定在屏幕的底部,而非随着文档流排布.要实现的样式可以概括如下: ...
- Dubbo学习-5-监控中心simpleMonitor搭建
之前已经下载好的dubbo-admin-master源码中,有dubbo-monitor-simple工程,同理,使用maven命令打包成一个可执行的jar包: 1.进入dubbo-monitor-s ...
- spring boot 参数传递(spring boot 参数传数 arg0 每一个参数 arg0#{arg0},arg1 #{arg1})
spring boot 参数传数 arg0 每一个参数 arg0#{arg0},arg1 #{arg1} @Select("select * from sys_user where nam ...
- 浅谈MySQL优化
本文整理了一些MySQL的通用优化方法,做个简单的总结分享,旨在帮助那些没有专职MySQL DBA的企业做好基本的优化工作,至于具体的SQL优化,大部分通过加适当的索引即可达到效果,更复杂的就需要具体 ...
- 用java实现文件的断点续传并发下载
需求: 支持文件批量下载.现在有很多小图片需要批量下载,不希望在服务器打包下载. 支持大文件断点下载.比如下载10G的文件. PC端全平台支持.Windows,macOS,Linux 全浏览器支持.i ...