「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. bootstrap-全局CSS&js插件

    一.全局CSS 1.概述 1. 全局CSS样式: * 按钮:class="btn btn-default" * 图片: * class="img-responsive&q ...

  2. flag&to do list&note

    没错,今天我要立几个看起来可能会倒的 flag 今天白天 早上除非有特殊情况,不许再看我的博客.不许再看我的qq空间.不许再跟别人聊闲话!!!☑已达成 今天早上一定要坚持做题,把昨天问老师的问题搞懂, ...

  3. AtCoder Beginner Contest 137 F

    AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...

  4. eclipse Target runtime com.genuitec.runtime.generic.jee50 is not defined

      1.情景展示 报错信息如下: 2.原因分析 使用eclipse导入myeclipse时,唯独这个报错信息改不了. 需要通过修改这个项目的配置文件才行. 3.解决方案 第一步:切换到导航视图: 第二 ...

  5. 性能测试-GC问题整理

    年轻代与老年代的调优(笔记整理) 几个常见名词 年轻代(young 区)从年轻代空间(包括Eden和Survivor 区域)回收内存被称为 Minor GC空间太小可能导致对象直接进入 old区 .如 ...

  6. GlusterFS 安装

    一.简介 GlusterFS 是近年兴起的一个高性能开源分布式文件系统,其目标是全局命名空间.分布式前端的高性能文件系统,目前已被 RedHat 看中,GlusterFS 具有高扩展.高可性.高性能. ...

  7. [BUAA软工]Beta阶段测试报告

    Beta阶段测试报告 Bug发现与报告 BUG 出现原因 解决方案 将shell加上编辑器UI以后,两边显示的文件不同步 两边的根目录不一致 修改编辑器获取根目录的函数,使其与shell的/home目 ...

  8. arthas安装进docker

    教程参照https://alibaba.github.io/arthas/arthas-tutorials mkdir /opt/downloads -pmkdir /opt/arthas -p下载地 ...

  9. 用Python实现一个简单的——人脸相似度对比

    近几年来,兴起了一股人工智能热潮,让人们见到了AI的能力和强大,比如图像识别,语音识别,机器翻译,无人驾驶等等.总体来说,AI的门槛还是比较高,不仅要学会使用框架实现,更重要的是,需要有一定的数学基础 ...

  10. HTML a标签链接 设置点击下载文件

    通常情况下,为文件添加链接后,用户可以通过点击链接,直接将文件下载到本地,如下载 excel 表格等 <a href="/user/test/xxxx.excel">点 ...