EVERYTHING HAPPENS FOR THE |

wnsyou

园龄:2年4个月粉丝:19关注:16

2024-07-20 13:57阅读: 17评论: 0推荐: 0

P3588 PUS 题解

PUS

推销我的洛谷博客。

题意

给出三个整数 n,s,m,请你构造一个整数数组 a 满足 1ai109(1in) 以及 m 个约束条件,或判断无解。a 数组中 s 个数已经给出(保证合法)。

m 个约束条件格式如下:l,r,k,x1,x2xk,表示对于 i,lir,ix,都有 aj>ai(jx)

如果存在一个满足要求的数组 a,输出 TAK,然后在下一行输出任意一种满足要求的 a;否则输出 NIE

数据范围

  • 1sn105,1m2×105
  • 1l<rn,1krl
  • lx1<x2<<xkr
  • k3×105

思路

线段树优化建图。

初步思路:将约束条件转为建图

题目要求构造一个合法的 a 数组,可以很显然的发现,当你从大到小的确定 a 中的元素时,ai 越大越好。

那么我们可以根据约束条件,建出一张由较大元素连向较小元素的有向图,最后根据这张图即可构造 a 数组(用 mii 表示所有连向它的元素的 aj 最小值,那么 ai 最大就为 mii1)。

如果是暴力建图,我们需要将每个 x 中的元素都连向其他在 [l,r] 中却不在 x 中的元素,很明显边的数量是 n2 级别的,无法接受。

建图的优化:集中点

如果做过 abc270_f Transportation 的话,你可以想到对于每个约束条件都建一个集中节点 id,将每个在 x 中的元素都连向 id,再将 id 连向每个在 [l,r] 中却不在 x 中的元素,边的数量便变成了 O(m×n+k),似乎更差劲了。

别着急,这都是为了为下一步优化做铺垫。

注意有一个细节,题目中约束条件是严格大于,所以 ai=mii1(参考上方),但对于这些集中点来说,他们并不用严格小于连向它的元素,即 mii=ai,需要特别注意。

建图再次优化:线段树优化建图

可以发现,id 暴力连向每个在 [l,r] 中却不在 x 中的元素的复杂度过大,但是我们能发现,与其使用暴力连单点,我们不如转换为连接区间,这样就可以使用线段树优化建图。

由于题目保证 k3×105,可以发现区间数量也是这个级别(只用考虑相邻两个 x 之间的区间 (xi,xi+1)),那么就好办了。

附:线段树优化建图的模板

最终:整理答案和判断无解

这个很简单,使用拓扑排序即可解决,注意上面所说的细节。

无解情况如下:

  • 在最优秀的构造方案中,你的 ai 肯定是尽量越大越好,所以当你发现某个 ai<1,那么必然是无解的。

  • 如果你发现最初已经给定了某个元素 ai 并且 mii1<ai,那么也是不合法的。

  • 如果出现了环,那么也是不合法的。

那么本题就结束了,还不理解就看代码。

复杂度

  • 时间:O(n+m+klogn)
  • 空间:O(n+m)

Code

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10, M = 2e5;
// ls 和 rs 用于记录线段树左右儿子,a 用于记录方案,b 是上文所说的 x,cnb 用于拓扑排序,mi 见上文
int n, m, s, rt, ncnt, ls[N * 3 + M], rs[N * 3 + M], a[3 * N + M], b[N], cnb[3 * N + M], mi[3 * N + M];
vector<int> g[N * 3 + M];
queue<int> q;
//----------------------------------------------------------------- 线段树优化建图
void Add_edge (int x, int y) {
g[y].push_back(x), cnb[x]++;
}
void build (int id, int l, int r) {
if (l == r) {
ls[id] = l;
Add_edge(l, id);
return ;
}
int mid = (l + r) >> 1;
ls[id] = ++ncnt, rs[id] = ++ncnt;
build(ls[id], l, mid), build(rs[id], mid + 1, r);
Add_edge(ls[id], id), Add_edge(rs[id], id);
}
void modify (int id, int l, int r, int x, int y, int u) {
if (x <= l && r <= y) {
Add_edge(id, u);
return ;
}
if (l > y || r < x)
return ;
int mid = (l + r) >> 1;
modify(ls[id], l, mid, x, y, u), modify(rs[id], mid + 1, r, x, y, u);
}
//----------------------------------------------------------------- 线段树优化建图
int main () {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> s >> m, ncnt = n;
rt = ++ncnt, build(rt, 1, n);
for (int i = 1, x, y; i <= s; i++)
cin >> x >> y, a[x] = y; // 最初给定的元素直接赋值即可
for (int x, k; m--; ) {
cin >> b[0] >> x >> k, ncnt++, b[0]--;
for (int i = 1; i <= k; i++) {
cin >> b[i], g[b[i]].push_back(ncnt), cnb[ncnt]++;
if (b[i] != b[i - 1] + 1) //只用管相邻两个元素之间的区间
modify(rt, 1, n, b[i - 1] + 1, b[i] - 1, ncnt);
}
if (x != b[k]) // 最后一个区间别漏了
modify(rt, 1, n, b[k] + 1, x, ncnt);
}
for (int i = 1; i <= ncnt; i++) // 初始化为 1e9 + 1 是为了方便下方减一
mi[i] = 1e9 + 1;
q.push(rt);
while (q.size()) {
int x = q.front();
q.pop();
if (a[x]) {// 初始时有数
if (mi[x] - 1 < a[x]) { // 判断无解情况 #2
cout << "NIE";
return 0;
}
} else {
a[x] = mi[x] - (x <= n); // 细节:集中点 a[i] = mi[i]
if (a[x] <= 0) { // 判断无解情况 #1
cout << "NIE";
return 0;
}
}
for (int i : g[x]) { // 拓扑排序都会写吧
mi[i] = min(mi[i], a[x]), cnb[i]--;
if (!cnb[i])
q.push(i);
}
}
for (int i = 1; i <= n; i++)
if (a[i] <= 0) { // 如果有环的话,肯定有元素没被赋值。判断无解情况 #1
cout << "NIE";
return 0;
}
cout << "TAK\n";
for (int i = 1; i <= n; i++)
cout << a[i] << ' ';
return 0;
}

本文作者:wnsyou

本文链接:https://www.cnblogs.com/wnsyou-blog/p/18313027/P3588_solution

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wnsyou  阅读(17)  评论(0编辑  收藏  举报
  1. 1 勝利への道 安藤浩和
  2. 2 Minecraft’s End Eric Fullerton
  3. 3 月光曲完整版 贝多芬 云熙音乐
  4. 4 平凡之路 (Live版) 朴树
  5. 5 Minecraft C418
  6. 6 Paradise NiziU
  7. 7 叫我,灰原哀 龙大人不喷火
  8. 8 心机之蛙,一直摸你肚子 ——《名侦探柯南》原创同人曲 炊饭,叶辞樱,温海,寒砧,南柯柯,小茜玛姬,盛姝,阿崔Ac,贝壳初,千湛,兮茶子DaYu,乔慕,黎鹿北,起千温卿,遮阳伞,曲悠
  9. 9 战 歌 此去经年
心机之蛙,一直摸你肚子 ——《名侦探柯南》原创同人曲 - 炊饭,叶辞樱,温海,寒砧,南柯柯,小茜玛姬,盛姝,阿崔Ac,贝壳初,千湛,兮茶子DaYu,乔慕,黎鹿北,起千温卿,遮阳伞,曲悠
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 一殇/白祺/苏少安/苏栗无/公子无央/白刃昏鸦/非欢/清茗/未及昭声/汀帆/赵艹地

作曲 : 沐若

心机之蛙,一直摸你肚子

——《名侦探柯南》原创同人曲

策划:炊饭

作曲:沐若

作词:一殇、白祺、苏少安、苏栗无、公子无央、白刃昏鸦、非欢、清茗、未及昭声、汀帆、赵艹地

编曲:斓音音乐实验室

演唱:叶辞樱、温海、寒砧、南柯、小茜玛姬、墨催、阿崔Ac、贝壳初、千湛、兮茶子、乔慕、黎鹿北、起千温卿、遮阳伞、曲悠

后期:幽谷

题字/美工:徒夫

监制:楠烛

【角色-词作-歌手】

【铃木园子-一殇-叶辞樱】

没有绝对杀机

爱恨调转 对错是唯一

【赤井秀一-白祺-温海】

枪膛里银色子弹

最后的致命一击

-

【毛利小五郎-苏少安-寒砧】

沉睡倒看真相 别小瞧绅士

叼烟来探 糊涂作势

【妃英理-白祺-南柯】

剥离出实情

透过谎言再续 不败传奇

-

【苏栗无-樱/砧/海/柯】

迷茫中看见吗 向谁的真谛

让谁的眼泪 都变成迷离

罪的答案是你 路的尽头是你

-

【怪盗基德-公子无央-小茜玛姬】

Kaitou 这雪白的谜语 将帽檐压低

以滑翔翼敬礼 向手铐和你

【服部平次-白刃昏鸦-墨催】

爱与真相是唯一

十字路口 迷宫的暗语

-

【灰原哀-非欢-乔慕】

回到少年时期 退化至逃离

像天才的过去 深海的鲨鱼

【毛利兰-非欢-起千温卿】

害怕妖怪和雷雨

正义和你 是我的勇气

-

【清茗-姬/催/慕/卿/悠】

天才与罪犯在探试 我已锁定案件起始

黑暗中蛰伏无休止 被贪欲吞噬

黄昏时 布谷钟请柬送至

跋涉深渊之池 侦探们的镇魂诗

-

【目暮十三-一殇-阿崔Ac】

樱花之名起誓

追寻真相 对罪恶通缉

【阿笠博士-苏少安-贝壳初】

古怪是科学正义

热衷将永不歇止

-

【安室透-白刃昏鸦-千湛】

被隐去的名姓 真伪皆归零

谜面重启 逆向独行

【琴酒-未及昭声-兮茶子】

用死亡美学 虔诚将你献祭

无声狙击

-

【汀帆-崔/初/湛/茶】

拨开重重迷题 信仰即期许

平扫僵阵地 守一方境域

且看如何踏破 早已残废终局

-

【江户川柯南-未及昭声-黎鹿北】

真相 折射在那镜片 透视在眼底

借时间逆行 拆穿真凶伏笔

【工藤新一-公子无央-遮阳伞】

骄傲是天才之理

逐一剖析 黑色的缝隙

-

【赵艹地-鹿/伞】

转动命运齿轮 去超越世纪

继续探查疑案 来解开谜题

【贝尔摩德-赵艹地-曲悠】

最喜爱伪装神秘

卷入迷雾 从容扣动扳机

-终-

加载中…

{{tag.name}}

{{tran.text}}{{tran.sub}}
无对应文字
有可能是
{{input}}
尚未录入,我来提交对应文字
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示