Portal

Description

给定一个长度为\(n(n\leq10^5)\)的正整数序列\(\{a_n\}\),每个数都在\([1,10^9]\)范围内,告诉你其中\(s\)个数,并给出\(m(m\leq2\times10^5)\)条信息。每条信息包含三个数\(L,R,k(Σk\leq 3\times10^5)\)以及\(k\)个正整数\(\{x_k\}\),表示\(a_L..a_R\)中,任意一个\(x\)均比剩下的\(R-L+1-k\)个数大(严格大于,即没有等号)。请任意构造出一组满足条件的方案,或者判断无解。

Solution

拓扑排序+线段树优化建图。

定义点权为\(val\);存在一条边权为\(w\)的边\((u,v)\)表示\(val[v]\geq val[u]+w\)。

首先考虑朴素的做法。建立\(n\)个点,\(val[i]\)表示\(a_i\)的值。对于每一条信息,新建一个点\(p\),\(val[p]\)表示\(min\{x_k\}\);剩下的数分别向\(p\)连一条边权为\(1\)的边(\(min\{x_k\}\)大于剩下的数),\(p\)向\(x_1..x_k\)分别连一条边权为\(0\)的边(\(x_i\)大于等于\(min\{x_k\}\))。初始时入度为\(0\)的点若没有值则令其\(val=1\),然后进行拓扑排序,如果成环或与初值冲突则无解。这样共有\(O(nm)\)条边。

考虑到边权为\(1\)的边的起点相当于\(k+1\)个区间,我们可以用线段树来优化建图。举例:\(n=8,a_3=7,a_5=4,a_7=2\),\([1,4]\)中最大的是\(\{2,3\}\),\([4,8]\)中是\(\{6\}\),\([1,8]\)中是\(\{2\}\)。



其中虚线边的权值为\(0\),实线边的权值为\(1\)。对于蓝线以上的点(线段树上的点),其\(val\)表示区间中的最大值;对于蓝线以下的点(条件所代表的点),其\(val\)表示\(min\{x_k\}\)。意义还是很明确的:例如边\(([3,4],\{2\})\)的权值为\(1\),表示\(min\{a_2\}>max\{3,4\}\)。同样机型拓扑排序并判断无解即可。至于边数...线段树上有\(2n\)条边,\(m\)条信息总共划分了\(m+Σk\)个区间,每个区间对应\(O(logn)\)条边,\(\{x_k\}\)共对应\(Σk\)条边;共计约\(2n+Σk+(m+Σk)logn\)条边。当然实际上要小很多,因为一条信息中所有区间的和是\([1,n]\),每个区间对应的边数远不足\(logn\)。算这么多干嘛直接开vector能过就行啊

Code

//[POI2015]Pustynia
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
inline char gc()
{
static char now[1<<16],*s,*t;
if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
return *s++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
inline int max(int x,int y) {return x>y?x:y;}
const int N=1e5+10;
int n,n1,m;
int cnt,rt,chL[N<<1],chR[N<<1];
const int N1=4e5+10;
int edCnt;
int val[N1],a[N1],in[N1],id[N];
vector< pair<int,bool> > son[N1];
inline void edAdd(int u,int v,bool w) {edCnt++; in[v]++; son[u].push_back(make_pair(v,w));}
void bldTr(int &p,int L0,int R0)
{
if(!p) p=++cnt;
if(L0==R0) {id[L0]=p; return;}
int mid=L0+R0>>1;
bldTr(chL[p],L0,mid),bldTr(chR[p],mid+1,R0);
edAdd(chL[p],p,0),edAdd(chR[p],p,0);
}
int optL,optR;
void trEdAdd(int p,int L0,int R0)
{
if(optL<=L0&&R0<=optR) {edAdd(p,cnt,1); return;}
int mid=L0+R0>>1;
if(optL<=mid) trEdAdd(chL[p],L0,mid);
if(mid<optR) trEdAdd(chR[p],mid+1,R0);
}
queue<int> Q;
int main()
{
n=read(),n1=read(),m=read();
bldTr(rt,1,n);
for(int i=1;i<=n1;i++) {int u=id[read()]; val[u]=a[u]=read();}
for(int i=1;i<=m;i++)
{
int L=read(),R=read(),k0=read();
cnt++; int pre=L;
while(k0--)
{
int x=read();
optL=pre,optR=x-1; if(optL<=optR) trEdAdd(rt,1,n);
pre=x+1; edAdd(cnt,id[x],0);
}
optL=pre,optR=R; if(optL<=optR) trEdAdd(rt,1,n);
}
for(int u=1;u<=cnt;u++) if(!in[u]) val[u]=max(1,a[u]),Q.push(u);
bool noAns=false;
while(!noAns&&!Q.empty())
{
int u=Q.front(); Q.pop();
if(a[u]&&val[u]>a[u]) {noAns=true; break;}
for(int i=0;i<son[u].size();i++)
{
int v=son[u][i].first,w=son[u][i].second;
val[v]=max(val[v],val[u]+w);
if(--in[v]==0) Q.push(v);
}
}
for(int u=1;u<=cnt&&!noAns;u++) if(in[u]||val[u]>1e9) noAns=true;
if(noAns) {puts("NIE"); return 0;}
puts("TAK");
for(int i=1;i<=n;i++) printf("%d ",val[id[i]]);
puts("");
return 0;
}

P.S.

每个数都在\([1,10^9]\)范围内! 意思是说如果你推出来有的数大于\(10^9\)就是无解,坑我半天...

洛谷P3588 - [POI2015]Pustynia的更多相关文章

  1. 洛谷P3588 [POI2015]PUS

    题面 sol:说了是线段树优化建图的模板... 就是把一整个区间的点连到一个点上,然后用那个点来连需要连一整个区间的点就可以了,就把边的条数优化成n*log(n)了 #include <queu ...

  2. 洛谷P3588 [POI2015]PUS(线段树优化建图)

    题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...

  3. 洛谷P3582 [POI2015]KIN

    题目描述 共有\(m\)部电影,编号为\(1--m\),第\(i\)部电影的好看值为\(w[i]\).在\(n\)天之中(从\(1~n\)编号)每天会放映一部电影,第\(i\)天放映的是第\(f[i] ...

  4. BZOJ 4385 洛谷3594 POI2015 WIL-Wilcze doły

    [题解] 手残写错调了好久QAQ...... 洛谷的数据似乎比较水.. n个正整数!!这很重要 这道题是个类似two pointer的思想,外加一个单调队列维护当前区间内长度为d的子序列中元素之和的最 ...

  5. 洛谷 P3586 [POI2015]LOG

    P3586 [POI2015]LOG 题目描述 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它 ...

  6. 洛谷 P3585 [POI2015]PIE

    P3585 [POI2015]PIE 题目描述 一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色.你有一个a*b的印章,有些格子是凸起(会沾上墨水)的.你需要判断能否用这个印章印出纸上 ...

  7. 洛谷P3586 [POI2015]LOG(贪心 权值线段树)

    题意 题目链接 Sol 显然整个序列的形态对询问没什么影响 设权值\(>=s\)的有\(k\)个. 我们可以让这些数每次都被选择 那么剩下的数,假设值为\(a_i\)次,则可以\(a_i\)次被 ...

  8. 洛谷P3585 [POI2015]PIE

    传送门 题目大意:有个n*m的格子图,要求'x'点要被染成黑色 有个a*b的印章,'x'是可以染色的印章上的点. 要求用印章去染色格子 (1)印章不可以旋转. (2)不能把墨水印到纸外面. (3)纸上 ...

  9. BZOJ 3747 洛谷 3582 [POI2015]Kinoman

    [题解] 扫描线+线段树. 我们记第i部电影上次出现的位置是$pre[i]$,我们从$1$到$n$扫描,每次区间$(pre[i],i]$加上第i部电影的贡献$w[f[i]]$,区间$[pre[pre[ ...

随机推荐

  1. Openjudge 2.5 6264:走出迷宫

    总时间限制:  1000ms 内存限制:  65536kB 描述 当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单. 假设你已经得到了一个n* ...

  2. Hibernate学习之简单应用

    前言:博主在学到Spring的时候,要开始做项目了,突然觉得好像有点虚,之前学过的Hibernate框架的简单应用好像又忘记了.所以返回来,做个小笔记. 简单来讲,Hibernate框架是利用对象-关 ...

  3. C++实现动态数组

    实现一个动态数组,要求对于随机访问可以在常数时间完成,可以通过push_back向数据的尾部追加元素,可以通过pop_back删除尾部元素,能够满足常见的数组操作. LINE 2016年春招笔试   ...

  4. 解决Starting to watch source with Jekyll and Compass. Starting Rack on port 4000

    问题 Starting to watch source with Jekyll and Compass. Starting Rack on port 4000 rake aborted! Errno: ...

  5. Example of how to implement a view-based source list (NSOutlineView) using Cocoa Bindings

    You tagged this with the cocoa-bindings tag, so I assume you mean "with bindings." I whipp ...

  6. canvas 在视频中的用法

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. js 返回上一页并刷新页面

    js 方法 代码如下 self.location=document.referrer;

  8. shell进阶

    shell 中的高级用法 1.if 单重判断 if cmd; then cmd cmd cmd fi 多重判断 单分支 if cmd;then cmd elif cmd fi 双分支 if cmd; ...

  9. lnmp一键安装包 虚拟主机问题

    lnmp一键安装包淌过的坑  --手动虚拟主机配置 安装一键包的时候教程 官网也有虚拟主机的教程 一下示例: 后来自己手动去做 就遇到了一个大家都遇到的问题 及时安装让nginx支持解析PHP脚本解析 ...

  10. docker:安装redis

    文章来源:https://www.cnblogs.com/hello-tl/p/9239474.html 1.添加镜像 # docker pull redis:4.0 2.在/data下新建文件夹re ...