「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 ...
随机推荐
- MSSQL数据库 1000W数据优化整理
GO SET STATISTICS TIME ON SELECT count([StyleId]) FROM [dbo].[Ky_Style] SET STATISTICS TIME OFF SET ...
- rancher2基础环境配置
一.主机配置 1.配置要求 参考节点要求 2.主机名配置 因为K8S的规定,主机名只支持包含 - 和 .(中横线和点)两种特殊符号,并且主机名不能出现重复. 3.Hosts 配置每台主机的hosts( ...
- Dynamic_Rankings(动态区间第k大)
ZOJ - 2112 \[ \ \] (那些说这道题是树状数组套主席树的人一定对主席树有误解!) 这里我们用树状数组套线段树来解决来写 首先 , 我们需要有n棵线段树(不是\(n^2\)空间,别慌) ...
- 一大波 Facebook Libra 技术文章来袭
由于 Libra 具有真正的稳定的可编程货币的特性, Libra 或许可以带来又一波平台红利. 上周我们(深入浅出区块链技术社区)发起了 Libra 技术文档的翻译计划,到这周文档已经翻译了一半.欢迎 ...
- BigDecimal代码示例
在平常开发中,如果涉及到计算,要求准确的精度,比如单价*数量=总价之类的计算,那么得用到BigDecimal. 初始化 如下: BigDecimal amount=new BigDecimal(&qu ...
- Redis内存数据库
remote dictionary server 远程字典服务器 Redis默认支持16个数据库,不同的应用应该使用不同的Redis实例存储数据. 支持数据类型:字符串,哈希散列,列表,集合,有序 ...
- WebGL学习笔记(十一):混合和透明
到目前为止我们绘制了不少模型,用到了不少颜色,颜色中有四个分量(RGBA),其中的A分量表示透明度,这个分量目前为止我们还没有真正的用到: A分量,表示的是当前的透明度,如果设定为 0.5 就会半透明 ...
- 工作流之activiti6新手上路
工作流的定义(解决什么问题?) 工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动 ...
- PHP 字符串和十六进制互转
今天在做项目中,因为要调用别人网站的接口,结果需要对请求和返回的时间进行十六进制加密处理,于是在网上查了下资料谢了一个转换Demo做个记录. 如果在TP下使用可以将下面函数放到common.php中 ...
- C语言设计模式
一 .C语言和设计模式(继承.封装.多态) C++有三个最重要的特点,即继承.封装.多态.我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性. ( ...