「UR#6」懒癌
「UR#6」懒癌
妈妈我居然看了六个小时题解,快救救乌干达的可怜儿童吧。
接下来开始膜官方题解:
其实就算有上面两个结论也不是很好想到任意复杂度的做法,关键在于要想到一个人是怎么推断自己的狗是不是懒狗的,这个过程显然不是 \(\mathcal O(1)\) 级别的。膜一下官方题解可以知道,一个人判断自己的狗是不是懒狗,会假设自己的狗不是懒狗,然后枚举一下其看不到的狗究竟是不是懒狗的各种情况,得到一个其想象的状态 \(S'\) ,如果所有 \(S'\) 的开枪时间都小于当前时刻,那么说明他的狗一定是懒狗,他就会开枪。
那么可以得到一个指数级别的做法,记 \(f[S]\) 表示 \(S\) 集合的开枪时间,枚举 \(S\) 中的每一条懒狗,在其主人所有想象的状态 \(S'\) 中取一个 \(\max(f[S'])+1\) ,表示这个人开枪的时间,最后在所有人的开枪时间里取一个 \(\min\) 。然后会发现转移实际上是有环的,有环实际上是有两个状态的时间都是对方开枪的时间 \(+1\) ,不难发现如果枚举其中一条懒狗的转移是有环的,那么这个状态中所有懒狗的转移都是会到达一个环的,因为出现环的情况的本质是有两个人互相看不到对方且其中至少一个人的狗是懒狗。
然后考虑把这张图的补图建出来,考虑转移有环的条件就是一个点能到达一个环,把这些点全部日掉就得到了一个 \(\text{DAG}\) ,我们把懒狗看做黑点,正常的狗看做白点,一个黑点集合的答案可以看做这样一个东西:
每次选取其中的一个黑点染白,然后将其所有后继节点染白,直到所有节点都变成白色,答案就是过程中被染黑的节点数量。为什么呢?考虑将一个节点从黑色被染成白色的时候看做选取了这个人来想象,这个时候它就假装自己不是懒狗了,所以染白,然后选取一些后继节点(看不见的节点)来钦定它们的黑白,这个时候加上一点贡献对应着原转移的 \(+1\) 。因为要取 \(\max\) 所以每次一定选的是所有的后继节点。而每个被染黑的节点只计算一次贡献是因为每次选择当前拓扑序最小的节点可以保证每个点只被染黑一次,这是一个永远可以取到的下界,对应着取 \(\min\) 操作。
那么一个节点对开枪时间有贡献当且仅当选取了一个黑点能到达它,对杀狗数量有贡献当且仅当所有选取的黑点除了它以外没节点能到达它,统计一下能到达每个点的点的数量即可,bitset搞搞,\(\mathcal O(\frac{n^3}{64})\) 。
题目中给了个条件,如果一个人听到枪声就不会开枪杀狗,过了以后膜了下jls发现这个条件是多余的。假设第 \(i\) 时刻有人开了一枪,在第 \(x\) 人在之后还会再开枪,那么他会推断出一个最晚开枪时间 \(j\),如果 \(j\) 之前没人开枪他就会在第 \(j\) 时刻开枪。如果 \(j <i\) ,那么这个人会先于 \(i\) 开枪,否则因为 \(i<j\) ,在 \(j\) 之前有人开枪,所以 \(x\) 不会开枪。
code
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef unsigned long long ull;
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 3005, mod = 998244353;
queue<int> q;
bitset<N> f[N], B[N];
char s[N];
int a[N][N], deg[N], inc[N], n, m, ans1, ans2;
inline void up(int &x, int y){
x = x + y >= mod ? x + y - mod : x + y;
}
inline int Pow(int a, int b){
int ans = 1;
for(; b; b >>= 1, a = 1ll * a * a % mod)
if(b & 1) ans = 1ll * ans * a % mod;
return ans;
}
inline void gao(int x){
up(ans1, (Pow(2, m) - Pow(2, m - x - 1) + mod) % mod);
up(ans2, (Pow(2, m - 1) - 1ll * (Pow(2, x) - 1) * Pow(2, m - x - 1) % mod + mod) % mod);
}
int main(){
read(n);
for(int i = 1; i <= n; i++){
scanf("%s", s + 1);
for(int j = 1; j <= n; j++)
a[i][j] = (s[j] == '0');
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++){
f[i][j] = a[i][j];
if(i == j) f[i][j] = 1;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(f[i][j]) f[i] |= f[j];
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
if(f[i][j] && f[j][i]) inc[i] = inc[j] = 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(f[i][j] && inc[j]) inc[i] = 1;
for(int i = 1; i <= n; i++) if(!inc[i]) m++;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(!inc[i] && !inc[j] && a[i][j] && i != j) deg[j]++;
for(int i = 1; i <= n; i++)
if(!inc[i] && !deg[i]) q.push(i);
for(; !q.empty(); q.pop()){
int u = q.front();
gao(B[u].count());
B[u][u] = 1;
for(int i = 1; i <= n; i++)
if(a[u][i] && !inc[i]){
B[i] |= B[u];
if(!--deg[i]) q.push(i);
}
}
cout << ans1 << " " << ans2 << endl;
return 0;
}
「UR#6」懒癌的更多相关文章
- 「UR#5」怎样跑得更快
「UR#5」怎样跑得更快 膜这个您就会了 下面是复读机mangoyang 我们要求 \[ \sum_{j=1}^n \gcd(i,j)^{c-d} j^d x_j=\frac{b_i}{i^d} \] ...
- 「UR#5」怎样更有力气
「UR#5」怎样更有力气 解题思路 考虑没有限制的情况,一定是把操作离线下来,按照边权从小到达做.可以发现,如果没有限制,完全图是多余的,直接拿树边进行合并就可以了.我们要做这么一件事情,把每个点属于 ...
- Solution -「UR #21」「UOJ #632」挑战最大团
\(\mathcal{Description}\) Link. 对于简单无向图 \(G=(V,E)\),定义它是"优美"的,当且仅当 \[\forall\{a,b,c,d\ ...
- Solution -「UR #2」「UOJ #32」跳蚤公路
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的带权有向图,每条边还有属性 \(s\in\{-1,0,1\}\).对于每个 \(u ...
- loj #2023. 「AHOI / HNOI2017」抛硬币
#2023. 「AHOI / HNOI2017」抛硬币 题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个 ...
- 前端构建工具之gulp(一)「图片压缩」
前端构建工具之gulp(一)「图片压缩」 已经很久没有写过博客了,现下终于事情少了,开始写博吧 今天网站要做一些优化:图片压缩,资源合并等 以前一直使用百度的FIS工具,但是FIS还没有提供图片压缩的 ...
- fir.im Weekly - 如何打造 Github 「爆款」开源项目
最近 Android 转用 Swift 的传闻甚嚣尘上,Swift 的 Github 主页上已经有了一次 merge>>「Port to Android」,让我们对 Swift 的想象又多 ...
- 更新日志 - fir.im「高级统计」功能上线
距离 2016 年到来只剩 10 个日夜,fir.im 也准备了一些新鲜的东西,比如「高级统计」功能和「跳转应用商店」功能,帮助你更好地管理.优化应用,欢迎大家试用反馈:) 新增高级统计功能 这次更新 ...
- Notepad++ 开启「切分窗口」同时检视、比对两份文件
Notepad++ 是个相当好用的免费纯文本编辑器,除了内建的功能相当多之外,也支持外挂模块的方式扩充各方面的应用.以前我都用 UltraEdit 跟 Emeditor,后来都改用免费的 Notepa ...
随机推荐
- mysql初始
数据(data) : -描述事物的符号记录称为数据,符号既可以是数据,文字,图片,声音,语言等,符号都可以经过数字化后存入计算机中 - 计算机中描述一个事物,就需要抽取这一事物的典型特征,组成一条记录 ...
- 「SDOI2014」旅行(信息学奥赛一本通 1564)(洛谷 3313)
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...
- java读取文件夹下文件及txt内容
public class PositionController { // 读取txt内容 public static String txt2String(File file) { ...
- [Beta阶段]第八次Scrum Meeting
Scrum Meeting博客目录 [Beta阶段]第八次Scrum Meeting 基本信息 名称 时间 地点 时长 第八次Scrum Meeting 19/05/14 大运村寝室6楼 25min ...
- centos7 python2.7升级至python3.5.3版本
1.wget https://www.python.org/ftp/python/3.5.3/Python-3.5.3.tgz #下载安装包 2.tar -zxvf Python-3.5.3 ...
- Android固件img文件的解包, 修改和打包的命令行操作
Android固件img文件的解包打包 To Unpack-Modify-Pach the system.img, I have followed the following procedure: a ...
- 累积分布函数(cumulative distribution function)
sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程,QQ:231469242) https://study.163.com/course/introduction.htm?courseId ...
- Error-ASP.NET:未能加载文件或程序集“CMSCalendar”或它的某一个依赖项。系统找不到指定的文件。
ylbtech-Error-ASP.NET:未能加载文件或程序集“CMSCalendar”或它的某一个依赖项.系统找不到指定的文件. 1.返回顶部 1. “/”应用程序中的服务器错误. 分析器错误 说 ...
- 带有Q_OBJECT的类要放在头文件的第一个类位置,否则可能无法moc
如果头文件中有多个类,带有Q_OBJECT的类要放在头文件的第一个类位置,否则可能无法moc
- 工控随笔_25_西门子TIA 博图V14.SP1安装报错,授权错误
前面有一篇文章说过西门子的软件安装的时候太麻烦,很容易出现错误. 但是有些错误在安装的时候却没有关系,例如下面的错误. 如上图所示,安装已经到最后一步,总结前面的修改系统组态已经打勾(✔) ,而且提示 ...