P5270 无论怎样神树大人都会删库跑路
题目地址:P5270 无论怎样神树大人都会删库跑路
第一眼看上去是模拟,似乎是 \(O(n)\) 的
水题
信心满满的写完:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 6;
int n, T, Q, m, c[N], r[N], mx, cnt, d[N], ans, s[N], now;
vector<int> e[N];
queue<int> q;
int main() {
cin >> n >> T >> Q;
for (int i = 1; i <= T; i++) {
int x;
scanf("%d", &x);
mx = max(mx, x);
++c[x];
}
for (int i = 1; i <= n; i++) {
int len;
scanf("%d", &len);
while (len--) {
int x;
scanf("%d", &x);
mx = max(mx, x);
e[i].push_back(x);
}
}
cin >> m;
for (int i = 1; i <= m; i++) scanf("%d", &r[i]);
for (int x = 0; x <= mx; x++) if (c[x] == d[x]) ++cnt;
for (int i = 1; i <= m && i <= Q; i++) {
for (unsigned int j = 0; j < e[r[i]].size(); j++) {
int x = e[r[i]][j];
q.push(x);
if (d[x] == c[x]) --cnt;
++d[x];
if (d[x] == c[x]) ++cnt;
}
while ((int)q.size() > T) {
int x = q.front();
q.pop();
if (d[x] == c[x]) --cnt;
--d[x];
if (d[x] == c[x]) ++cnt;
}
if (cnt == mx + 1) ++ans;
}
if (Q <= m) {
cout << ans << endl;
return 0;
}
Q -= m;
for (int i = 1; i <= m; i++) {
for (unsigned int j = 0; j < e[r[i]].size(); j++) {
int x = e[r[i]][j];
q.push(x);
if (d[x] == c[x]) --cnt;
++d[x];
if (d[x] == c[x]) ++cnt;
}
while ((int)q.size() > T) {
int x = q.front();
q.pop();
if (d[x] == c[x]) --cnt;
--d[x];
if (d[x] == c[x]) ++cnt;
}
if (cnt == mx + 1) ++now;
s[i] = now;
}
cout << ans + now * (Q / m) + s[Q%m] << endl;
return 0;
}
Wait!
Q:为什么在模拟完第一遍后要再模拟一遍呢?
A:第一遍初始时没有数,而后面会有剩下的数留到下一轮,因此第一遍对 \(ans\) 的贡献要特判QAQ
一遍AC
然而......
模拟是 \(O(n)\) 的?
抱歉,假了,50分滚粗
康康这组数据:
1 1e5 1e9
1 1 ... 1
1e5 1 1 ... 1
1e5
1 1 ... 1
你会发现
被卡成 \(O(n^2)\) 了!
Q:怎么办?
A:骂毒瘤出题人
我们发现瓶颈在这:
for (unsigned int j = 0; j < e[r[i]].size(); j++) {
int x = e[r[i]][j];
q.push(x);
if (d[x] == c[x]) --cnt;
++d[x];
if (d[x] == c[x]) ++cnt;
}
while ((int)q.size() > T) {
int x = q.front();
q.pop();
if (d[x] == c[x]) --cnt;
--d[x];
if (d[x] == c[x]) ++cnt;
}
这个插入删除是 \(O(n)\) 的!
Q:我们能不能把它搞成 \(O(1)\) 的?
A:可以
考虑 Hash 思想
先看代码:
#include <bits/stdc++.h>
#define ull unsigned long long
#define pii pair<int, int>
using namespace std;
const int N = 1e5 + 6;
int n, T, Q, S[N], R[N], m, mx, len, ans, s[N], kkk;
vector<int> e[N];
struct H {
ull h[6];
H() {
memset(h, 0, sizeof(h));
}
} Hash[N], numS, now;
vector<H> num[N];
deque<pii> q;
inline ull RA() {
return (ull)rand() * rand() * rand() * rand() * rand() * rand();
}
inline void add(H &a, H &b) {
for (int i = 0; i < 6; i++) a.h[i] += b.h[i];
}
inline void del(H &a, H &b) {
for (int i = 0; i < 6; i++) a.h[i] -= b.h[i];
}
inline bool equ(H a, H b) {
for (int i = 0; i < 6; i++)
if (a.h[i] != b.h[i]) return 0;
return 1;
}
int main() {
srand((unsigned)time(0));
cin >> n >> T >> Q;
for (int i = 1; i <= T; i++) {
scanf("%d", &S[i]);
mx = max(mx, S[i]);
}
for (int i = 1; i <= n; i++) {
int len;
scanf("%d", &len);
while (len--) {
int x;
scanf("%d", &x);
mx = max(mx, x);
e[i].push_back(x);
}
}
cin >> m;
for (int i = 1; i <= m; i++) scanf("%d", &R[i]);
for (int i = 0; i <= mx; i++)
for (int j = 0; j < 6; j++)
Hash[i].h[j] = RA();
for (int i = 1; i <= T; i++) add(numS, Hash[S[i]]);
for (int i = 1; i <= n; i++) {
int len = e[i].size();
num[i].resize(len);
for (int j = len - 1; ~j; j--)
add(num[i][j], Hash[e[i][j]]);
for (int j = len - 2; ~j; j--)
add(num[i][j], num[i][j+1]);
}
for (int i = 1; i <= m && i <= Q; i++) {
add(now, num[R[i]][0]);
len += e[R[i]].size();
q.push_back({R[i], 0});
while (len > T) {
pii x = q.front();
q.pop_front();
del(now, num[x.first][x.second]);
len -= e[x.first].size() - x.second;
if (len < T) {
int k = num[x.first].size() - (T - len);
q.push_front({x.first, k});
add(now, num[x.first][k]);
len = T;
}
}
if (equ(now, numS)) ++ans;
}
if (Q <= m) {
cout << ans << endl;
return 0;
}
Q -= m;
for (int i = 1; i <= m && i <= Q; i++) {
add(now, num[R[i]][0]);
len += e[R[i]].size();
q.push_back({R[i], 0});
while (len > T) {
pii x = q.front();
q.pop_front();
del(now, num[x.first][x.second]);
len -= e[x.first].size() - x.second;
if (len < T) {
int k = num[x.first].size() - (T - len);
q.push_front({x.first, k});
add(now, num[x.first][k]);
len = T;
}
}
if (equ(now, numS)) ++kkk;
s[i] = kkk;
}
cout << ans + kkk * (Q / m) + s[Q%m] << endl;
return 0;
}
(小声)不好意思kkk,窝真的是没有变量名可用才用您的QWQ
我们给每个数若干维随机 Hash 值
for (int i = 0; i <= mx; i++)
for (int j = 0; j < 6; j++)
Hash[i].h[j] = RA();
一串数的 Hash 值定义为每个数的每一维 Hash 分别相加(unsigned long long自然溢出)
如果两个串任意排列后可以相同,这两个串对应的每一维都应该相同
那么插入和删除就都可以做到 \(O(1)\) 了
你卡我随机化鸭
你卡我 Hash 鸭
你卡我常数大鸭
P5270 无论怎样神树大人都会删库跑路的更多相关文章
- Mysql binlog备份数据及恢复数据,学会这个,我在也不怕删库跑路啦~
导读 我一直都主张,技多不压身(没有学不会的技术,只有不学习的人),多学一项技能,未来就少求人一次.网上经常听到xxx删库跑路,万一真的遇到了,相信通过今天的学习,也能将数据再恢复回来~~~ 当然啦, ...
- Oracle删库跑路
--10g R2 startup mount exclusive restrict; alter system enable restricted session; drop database; -- ...
- SQL 从入门到 DBA 删库跑路
SQL 从入门到 DBA 删库跑路 一.基础 人员信息表: ID 姓名 性别 出生 婚否 学历 工资 工会 35009449 孙xx 男 1978-2-17 未婚 中专 3000 TRUE 35000 ...
- 数据误操作,删库跑路?教你使用ApexSQLLog工具从 SQLServer日志恢复数据!
前几天同事不小心误操作,将SQLServer库的一张表的一个状态字段给刷成了一个统一状态,由于是update执行所以原来的相关状态无法确定.发生这种事情的时候我的小伙伴背后 一凉,估计心里里面想这怕是 ...
- 教你如何6秒钟往MySQL插入100万条数据!然后删库跑路!
教你如何6秒钟往MySQL插入100万条数据!然后删库跑路! 由于我用的mysql 8版本,所以增加了Timezone,然后就可以了 前提是要自己建好库和表. 数据库test, 表user, 三个字段 ...
- 【巨杉数据库SequoiaDB】巨杉Tech | “删库跑路”又出现,如何防范数据安全风险?
最近,又双叕有企业被“删库”了.来自微盟官网的消息,微盟的业务系统数据库(包括主备)遭遇其公司运维人员的删除,系统将停止运营超48小时. 频发的类似事件也让大家对于数据安全的关注不断提高.数据是一个科 ...
- The Data Way Vol.3|做到最后只能删库跑路?DBA 能做的还有很多
关于「The Data Way」 「The Data Way」是由 SphereEx 公司出品的一档播客节目.这里有开源.数据.技术的故事,同时我们关注开发者的工作日常,也讨论开发者的生活日常:我们聚 ...
- 因为它,我差点删库跑路:js防抖与节流
前言 前端踩雷:短时间内重复提交导致数据重复. 对于前端大佬来说,防抖和节流的技术应用都是基本操作.对于"兼职"前端开发的来说,这些都是需要躺平的坑. 我们今天就来盘一盘js防抖与 ...
- 大数据开发从入门小白到删库跑路(一)- 获取Hadoop
Hadoop是一个可以通过相对简单编程模型实现跨多台计算机集群分布式处理大型数据集的框架.它不是依赖于高额成本的硬件可靠性来提供高可用性,Hadoop的设计能从单个服务器扩展到数千台机器,每个机器提供 ...
随机推荐
- M1-Flask-Day1
前情概要 1.flask的基本使用 - 配置 - 路由 - 视图 - 请求与响应相关 - 模板 2.flask基于装饰器实现的路由 - 基本操作 - functools - 带参数的装饰器 - 源码剖 ...
- hadoop mapreduce 基础实例一记词
mapreduce实现一个简单的单词计数的功能. 一,准备工作:eclipse 安装hadoop 插件: 下载相关版本的hadoop-eclipse-plugin-2.2.0.jar到eclipse/ ...
- 虚拟机部署hadoop集群准备工作之多虚拟机设置网络信息
安装好了centos6.4(最简版)后 1,静态IP设置 查看虚拟机的网络设置信息来配置
- netty的数据通信之心跳检测
问题1:我们想实现客户端和服务端建立连接之后,5秒钟之后如果没有数据传输就关闭与客户端的连接. 解决办法:在服务端加上下面一条代码 ch.pipeline().addLast(new ReadTime ...
- jdom使用入门及namespace注意事项【原】
报文样例 <person:info xmlns:person="http://person/abc" id="1"> <fruit id=&q ...
- C#实现的系统内存清理
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...
- 前端面试题整理—HTML/CSS篇
1.简述一下你对HTML语义化的理解 1)用正确的标签做正确的事情 2)html语义化让页面的内容结构化,结构更清晰,便于对浏览器.搜索引擎解析 3)即使在没有样式CSS情况下也以一种文档格式显示,并 ...
- springboot(十四):springboot整合mybatis
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;bounda ...
- Javaweb学习笔记——(九)——————Servlet的进入,及ServletConfig、GenericServlet、HttpServlet、ServletContext、获取类路径资源
Servlet1.什么是Servlet? *Servlet是Javaweb三大组件之一(Servlet,Filter,Listener) *Servlet是用来处理客户端请求的动态资源 *Servle ...
- 【SRM-05 B】无题?
Description 有一个拥有n个城市的国家.这个国家由n-1条边连接起来.有一天国家发生叛乱.叛军已占领了一些城市.如果叛军占领的城市中,存在两个城市之间有边直接相连,则称这种情况是坏的.现在并 ...