「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」懒癌的更多相关文章

  1. 「UR#5」怎样跑得更快

    「UR#5」怎样跑得更快 膜这个您就会了 下面是复读机mangoyang 我们要求 \[ \sum_{j=1}^n \gcd(i,j)^{c-d} j^d x_j=\frac{b_i}{i^d} \] ...

  2. 「UR#5」怎样更有力气

    「UR#5」怎样更有力气 解题思路 考虑没有限制的情况,一定是把操作离线下来,按照边权从小到达做.可以发现,如果没有限制,完全图是多余的,直接拿树边进行合并就可以了.我们要做这么一件事情,把每个点属于 ...

  3. Solution -「UR #21」「UOJ #632」挑战最大团

    \(\mathcal{Description}\)   Link.   对于简单无向图 \(G=(V,E)\),定义它是"优美"的,当且仅当 \[\forall\{a,b,c,d\ ...

  4. Solution -「UR #2」「UOJ #32」跳蚤公路

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的带权有向图,每条边还有属性 \(s\in\{-1,0,1\}\).对于每个 \(u ...

  5. loj #2023. 「AHOI / HNOI2017」抛硬币

    #2023. 「AHOI / HNOI2017」抛硬币   题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个 ...

  6. 前端构建工具之gulp(一)「图片压缩」

    前端构建工具之gulp(一)「图片压缩」 已经很久没有写过博客了,现下终于事情少了,开始写博吧 今天网站要做一些优化:图片压缩,资源合并等 以前一直使用百度的FIS工具,但是FIS还没有提供图片压缩的 ...

  7. fir.im Weekly - 如何打造 Github 「爆款」开源项目

    最近 Android 转用 Swift 的传闻甚嚣尘上,Swift 的 Github 主页上已经有了一次 merge>>「Port to Android」,让我们对 Swift 的想象又多 ...

  8. 更新日志 - fir.im「高级统计」功能上线

    距离 2016 年到来只剩 10 个日夜,fir.im 也准备了一些新鲜的东西,比如「高级统计」功能和「跳转应用商店」功能,帮助你更好地管理.优化应用,欢迎大家试用反馈:) 新增高级统计功能 这次更新 ...

  9. Notepad++ 开启「切分窗口」同时检视、比对两份文件

    Notepad++ 是个相当好用的免费纯文本编辑器,除了内建的功能相当多之外,也支持外挂模块的方式扩充各方面的应用.以前我都用 UltraEdit 跟 Emeditor,后来都改用免费的 Notepa ...

随机推荐

  1. CF859E Desk Disorder

    传送门 Luogu Solution 好好思考一下,发现人和座位构成的是一个二分图这还用想? 那么这个时候发现其实我们要求的就是这个二分图完全匹配的方案数,考虑在二分图上的一个连通块,如果是树,那么就 ...

  2. [NOIP2013]华容道 题解

    [NOIP2013]华容道 首先是一种比较显然的做法. 整个棋盘,除了起点,终点和空格,其他的方块是等价的. 对于终点,它始终不会变化,如果搜到终点结束搜索即可,所以我们不需要考虑终点. 所以需要考虑 ...

  3. 《京东B2B业务架构演变》阅读笔记

    一.京东 B2B 业务的定位 让各类型的企业都可以在京东的 B 平台上进行采购.建立采购关系. 京东 B2B 的用户群体主要分为 2 类: 一类是大 B 用户.另一类是小 B 用户.京东 B 平台需要 ...

  4. python 文字转语音

    # coding=utf-8 import pyttsx3 text='I love you 韩长菊' voice=pyttsx3.init() voice.say(text) voice.runAn ...

  5. 对回溯算法的理解(以数独游戏为例,使用c++实现)

    算法思想: 数独游戏的规则: 每一行都用到1.2.3.4.5.6.7.8.9位置不限: 每一列都用到1.2.3.4.5.6.7.8.9位置不限: 每3×3的格子(共九个这样的格子)都用到1.2.3.4 ...

  6. TP 控制器和模型里面order 写法不同

      控制器: Db::table('think_user')->where('status=1')->order('id desc')->limit(5)->select(); ...

  7. Mac Mini 2014 更换SSD 升级SSD

    将自己的Mac Mini 2014版升级成固态硬盘 亲自动手, 还算顺利, 参考网络教程, 并改进了里面的关键步骤, 下面是原文链接 Mac Mini 2014 升级成SSD Mac Mini 拆机图 ...

  8. roboware 常见操作和问题

    博客参考:https://blog.csdn.net/u013528298/article/details/88052470 1. build中错误位置定位方式 按住“CTRL”键并点击错误提示的链接 ...

  9. Tensorflow不同版本要求与CUDA及CUDNN版本对应关系

    参考官网地址: Windows端:https://tensorflow.google.cn/install/source_windows CPUVersion Python version Compi ...

  10. Caused by java.lang.Exception Failed to send data to Kafka Expiring

    flink 写kafka,报错,作业挂掉 Caused by: java.lang.Exception: Failed to send data to Kafka: Expiring 89 recor ...