题解 [PA2019]Trzy kule
Description
对于两个长度为 \(n\) 的 \(01\) 串 \(a_1,a_2,\dots,a_n\) 和 \(b_1,b_2,\dots,b_n\),定义它们的距离 \(d(a,b)=\sum_{i=1}^{n}|a_i-b_i|\)。
给定三个长度为 \(n\) 的 \(01\) 串 \(s_1,s_2,s_3\) 以及三个非负整数 \(r_1,r_2,r_3\),问有多少个长度为 \(n\) 的 \(01\) 串 \(S\) 满足 \(d(S,s_1)\le r_1,d(S,s_2)\le r_2,d(S,s_3)\le r_3\) 这三个不等式中至少有一个成立。
\(1\le n\le 10^4\)
Solution
总的来说,这个题目是一个比较有技巧性的题目。
首先我们可以想到对原问题进行容斥,即我们计算有多少个 \(S\) 序列满足 \(d(S,s_1)>r_1,d(S,s_2)>r_2,d(S,s_3)>r_3\),然后再用 \(2^n\) 减去即可。
接着,我们可以发现我们可以稍微变化一下,使得相对关系不变且 \(s_1\) 为全 \(1\) 序列,那么对于同一个位置 \(s_1,s_2,s_3\) 就只会有 \(4\) 种情况:\((1,0,0),(1,0,1),(1,1,0),(1,1,1)\)。
考虑计算每种情况的个数,并且枚举每种情况的位置多少个放 \(0\),多少个放 \(1\) 就可以做到 \(\Theta(n^4)\)。
考虑到我们可以利用我们已知的信息列不等式,然后我们就只需要枚举两种,剩下的可以预处理求个后缀和就好了。
复杂度 \(\Theta(n^2)\)。
Code
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define mod 1000000007
#define MAXN 10005
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}
char fs[3][MAXN];
int n,r[3],sum[4],s[3][MAXN],fac[MAXN],ifac[MAXN],f[MAXN][MAXN];
int mul (int a,int b){return 1ll * a * b % mod;}
int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
int gcd (int a,int b){return !b ? a : gcd (b,a % b);}
int qkpow (int a,int b){
int res = 1;for (;b;b >>= 1,a = mul (a,a)) if (b & 1) res = mul (res,a);
return res;
}
int binom (int a,int b){return a >= b ? mul (fac[a],mul (ifac[b],ifac[a - b])) : 0;}
void Add (int &a,int b){a = add (a,b);}
void Sub (int &a,int b){a = dec (a,b);}
signed main(){
read (n);
fac[0] = 1;for (Int i = 1;i <= n;++ i) fac[i] = mul (fac[i - 1],i);
ifac[n] = qkpow (fac[n],mod - 2);for (Int i = n;i;-- i) ifac[i - 1] = mul (ifac[i],i);
for (Int i = 0;i < 3;++ i){
read (r[i]),scanf ("%s",fs[i] + 1);
for (Int k = 1;k <= n;++ k) s[i][k] = (fs[i][k] - '0');
}
for (Int k = 1;k <= n;++ k) if (!s[0][k]) s[0][k] ^= 1,s[1][k] ^= 1,s[2][k] ^= 1;
for (Int k = 1;k <= n;++ k) sum[s[1][k] << 1 | s[2][k]] ++;
for (Int i = 0;i <= sum[2] + sum[3];++ i)
for (Int j = -sum[2];j <= sum[3];++ j) if (!(i + j & 1)){
int s3 = i + j >> 1,s2 = i - s3;
if (0 <= s2 && s2 <= sum[2] && 0 <= s3 && s3 <= sum[3])
Add (f[i][j + sum[2]],mul (binom (sum[2],s2),binom (sum[3],s3)));
}
for (Int i = sum[2] + sum[3];i >= 0;-- i)
for (Int j = sum[3];j >= -sum[2];-- j) Add (f[i][j + sum[2]],f[i][j + 1 + sum[2]]);
for (Int i = sum[2] + sum[3];i >= 0;-- i)
for (Int j = sum[3];j >= -sum[2];-- j) Add (f[i][j + sum[2]],f[i + 1][j + sum[2]]);
int ans = 0,all = 1;
for (Int i = 1;i <= n;++ i) all = add (all,all);
for (Int s0 = 0;s0 <= sum[0];++ s0)
for (Int s1 = 0;s1 <= sum[1];++ s1){
int v1 = max (0,max (r[0] - s0 - s1,r[1] + s0 + s1 - sum[0] - sum[1]) + 1),
v2 = max (-sum[2],r[2] + s0 - s1 - sum[0] - sum[2] + 1);
Add (ans,mul (mul (binom (sum[0],s0),binom (sum[1],s1)),f[v1][v2 + sum[2]]));
}
write (dec (all,ans)),putchar ('\n');
return 0;
}
题解 [PA2019]Trzy kule的更多相关文章
- Potyczki Algorythmiczne 2019
Runda próbna: A + B 设$f[i]$表示两数相加得到前$i$位的方案数,由$f[i-1]$和$f[i-2]$转移得到. #include<cstdio> #include ...
- 「题解」PA2019 Terytoria
本文将同步发布于: 洛谷博客: csdn: 博客园: 因为简书系统升级,所以本文未在简书上发布. 题目 题目链接:洛谷 P5987.LOJ 3320.官网. 题意概述 在二维平面直角坐标系上,有一个长 ...
- POI2015题解
POI2015题解 吐槽一下为什么POI2015开始就成了破烂波兰文题目名了啊... 咕了一道3748没写打表题没什么意思,还剩\(BZOJ\)上的\(14\)道题. [BZOJ3746][POI20 ...
- 【BZOJ4384】[POI2015]Trzy wieże 树状数组
[BZOJ4384][POI2015]Trzy wieże Description 给定一个长度为n的仅包含'B'.'C'.'S'三种字符的字符串,请找到最长的一段连续子串,使得这一段要么只有一种字符 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
随机推荐
- MySQL授权认证
• MySQL-权限系统介绍 • 权限系统的作用是授予来自某个主机的某个用户可以查询.插入.修改.删除等数据库操作的权限 • 不能明确的指定拒绝某个用户的连接 • 权限控制(授权与回收)的执行语句包括 ...
- nginx 开启,关闭,重启
2021-08-191. 启动 # 判断配置文件是否正确 cd /usr/local/nginx/sbin ./nginx -t # 启动 cd usr/local/nginx/sbin ./ngin ...
- Kotlin之内联回调函数
let 定义: let扩展函数的实际上是一个作用域函数,当你需要去定义一个变量在一个特定的作用域范围内,let函数的是一个不错的选择:let函数另一个作用就是可以避免写一些判断null的操作. 翻译: ...
- docker开启remote-api 2375端口后,Failed to start Docker Application Container Engine,重启docker失败的问题解决
1. 按照网上的教程修改了 /usr/lib/systemd/system/docerk.service配置后,重启失败.修改/etc/docker/daemon.json 增加hosts后重启也是 ...
- Qt学习日记篇-Qt中使用Curl和jsonCpp
1.Qt中安装并使用jsonCPP库 1.1 官网下载.https://sourceforge.net/projects/jsoncpp/ 解压文件得到 jsoncpp-src-0.5.0 文 ...
- 分布式技术专题-分布式协议算法-带你彻底认识Paxos算法、Zab协议和Raft协议的原理和本质
内容简介指南 Paxo算法指南 Zab算法指南 Raft算法指南 Paxo算法指南 Paxos算法的背景 [Paxos算法]是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息 ...
- SSL基础知识及Nginx/Tomcat配置SSL
HTTPS 是在 HTTPS 基础之上添加 SSL/TLS 使网络通讯加密,进而确保通信安全.可简记为 HTTPS = HTTP + SSL/TLS 本文档主要讲解常规SSL格式.Nginx 与 To ...
- Spring AOP 事务配置(实现转账事务)
1. 事务特性 事务特性:ACID 原子性:整体 [原子性是指事务包含的所有操作要么全部成功,要么全部失败] 一致性:数据 [一个事务执行之前和执行之后都必须处于一致性状态] 隔离性:并发 [对于任意 ...
- Intel® QAT加速卡之Ring & Ring Bank
1. QAT的应用模式 Intel 通讯系列芯片对于每种受支持的加速服务(加密,数据压缩),都支持以下应用模式: 内核模式,其中应用程序和加速服务都在内核中运行空间. 用户空间直接访问在用户空间中运行 ...
- python3 爬虫五大模块之二:URL管理器
Python的爬虫框架主要可以分为以下五个部分: 爬虫调度器:用于各个模块之间的通信,可以理解为爬虫的入口与核心(main函数),爬虫的执行策略在此模块进行定义: URL管理器:负责URL的管理,包括 ...