RMQ问题是一类区间最值问题,这里给出一个特殊的RMQ问题,初始给定一个n长的排列P,注:n长排列是指有1~n这n个整数构成的一个序列每个整数恰好出现一次。并对这个排列P进行M次查询操作,每次查询形如Query(L,R),每次查询返回排列P中位置在区间[L,R]上所有数中最大的那个数,其中位置的下标从1开始。例如排列P = {3,1,4,2,5},

那么Query(1,2) = max{3,1}=3,Query(2,4)=max{1,4,2}=4。由于RMQ问题对大家来说实在是太简单了,所以这题要求大家求解一个RMQ的逆问题,即给你排列的长度n,以及M次查询的问题及其结果三元组(Li,Ri,Qi),即Query(Li,Ri)=Qi,询问符合这M次查询的n长排列是否存在。若存在输出“Possible”;否则输出“Impossible”。
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5
之后有T组结构相同的数据:
每组数据的第一行有两个整数n与M,其中1<=n<=10^9(即1,000,000,000),1<=M<=50
之后会有M行,每行表示一个三元组Li,Ri,Qi,其中1<=Li<=Ri<=n,1<=Qi<=n
Output
每组数据输出一行,即“Possible”或“Impossible”不含引号

对于一个询问(L,R,Q),能得到的信息是(Q,n]中的数只能在[1,L)或(R,n],Q只能在[L,R]

因此离散化之后可以转化为最大流,左边的点代表每个数值/数值区间,右边的点代表每个区间,之间连边inf代表此数值可以在此区间内,源点到左边的点连边限制每个数值/数值区间中数值的个数,右边的点连边到汇点限制每个区间内数值的个数,当且仅当最大流为n时有解

#include<cstdio>
#include<algorithm>
const int N=,inf=0x3f3f3f3f;
int es[N],enx[N],ev[N],e0[N],ep;
int h[N],q[N],S,T;
inline void adde(int a,int b,int c){
es[ep]=b;enx[ep]=e0[a];ev[ep]=c;e0[a]=ep++;
es[ep]=a;enx[ep]=e0[b];ev[ep]=;e0[b]=ep++;
}
bool bfs(){
int ql=,qr=;
for(int i=;i<=T;i++)h[i]=;
h[S]=;q[qr++]=S;
while(ql!=qr){
int w=q[ql++];
for(int i=e0[w];i;i=enx[i]){
int u=es[i];
if(!h[u]&&ev[i]){
h[u]=h[w]+;
q[qr++]=u;
}
}
}
return h[T];
}
int dfs(int w,int f){
if(w==T)return f;
int c,u,used=;
for(int i=e0[w];i;i=enx[i]){
u=es[i];
if(h[u]!=h[w]+||!ev[i])continue;
c=f-used;
if(c>ev[i])c=ev[i];
c=dfs(u,c);
used+=c;
ev[i]-=c;
ev[i^]+=c;
if(used==f)return f;
}
if(!used)h[w]=;
return used;
}
int qs[][],xs[],ps[],xp,pp;
bool d[][];
int main(){
int _T,n,q;
for(scanf("%d",&_T);_T;_T--){
scanf("%d%d",&n,&q);
for(int i=;i<q;i++)scanf("%d%d%d",qs[i],qs[i]+,qs[i]+);
xp=pp=;
xs[xp++]=;
xs[xp++]=n+;
ps[pp++]=;
ps[pp++]=n+;
for(int i=;i<q;i++){
xs[xp++]=qs[i][];
xs[xp++]=qs[i][]+;
ps[pp++]=qs[i][];
ps[pp++]=qs[i][]+;
}
std::sort(xs,xs+xp);
xp=std::unique(xs,xs+xp)-xs;
std::sort(ps,ps+pp);
pp=std::unique(ps,ps+pp)-ps;
for(int i=;i<xp;i++)for(int j=;j<pp;j++)d[i][j]=;
for(int i=;i<q;i++){
for(int j=;j<xp-;j++){
if(xs[j]>qs[i][]){
for(int k=;k<pp-;k++)if(qs[i][]<=ps[k]&&ps[k]<=qs[i][]){
d[j][k]=;
}
}else if(xs[j]==qs[i][]){
for(int k=;k<pp-;k++)if(qs[i][]>ps[k]||ps[k]>qs[i][]){
d[j][k]=;
}
}
}
}
S=xp+pp+;T=S+;
for(int i=;i<=T;i++)e0[i]=;
ep=;
for(int i=;i<xp-;i++)adde(S,i+,xs[i+]-xs[i]);
for(int i=;i<pp-;i++)adde(xp+i+,T,ps[i+]-ps[i]);
for(int i=;i<xp-;i++)for(int j=;j<pp-;j++)if(d[i][j])adde(i+,xp+j+,n);
int ans=;
while(bfs())ans+=dfs(S,inf);
puts(ans==n?"Possible":"Impossible");
}
return ;
}

51nod 1336 RMQ逆问题的更多相关文章

  1. 51Nod1336 RMQ逆问题 其他

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1336.html 题目传送门 - 51Nod1336 题意 题解 我们将输入的一个区间的答案称为 V ...

  2. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

    题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...

  3. 51nod 1272【二分+RMQ】

    思路: 这题不能说是长见识,倒是第一次写这么富有套路的题,倒着来,二分区间嘛,这个很简单啊,二分的条件查询一个当前区间的最小值是不是比那个特定的值小,一步步缩小,这就是二分嘛,然后查询用线段树的RMQ ...

  4. 51Nod 1174 区间中最大的数(RMQ)

    #include <iostream> #include <algorithm> #include <cstring> using namespace std; + ...

  5. 51nod1174(RMQ)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1174 题意:中文题诶- 思路:RMQ模板题 关于RMQ: h ...

  6. 51nod 1050 循环数组最大子段和 单调队列优化DP

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 这个呢,这个题之前 求一遍最大值  然后求一遍最小值 ...

  7. 【51Nod 1244】莫比乌斯函数之和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...

  8. 51Nod 1268 和为K的组合

    51Nod  1268  和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...

  9. 51Nod 1428 活动安排问题

    51Nod   1428  活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...

随机推荐

  1. Open vSwitch 给虚拟机网卡限流(QoS)

    这里我们简单描述下如何通过Open vSwitch给虚拟机限流(出流量),同时测试限流效果.测试环境继续复用<整合Open vSwitch与DNSmasq为虚拟机提供DHCP功能>一文中描 ...

  2. 八 JDBC

    一 JDBC 简介 1. 作用:规避数据库的不同,为程序开发人员访问数据库提供统一的编程接口. 2. 具体作用:和数据库建立连接,发送 sql 语句,处理数据库返回的结果集. 3. 框架模式: 4. ...

  3. C++ Primer : 第十二章 : 动态内存之shared_ptr与new的结合使用、智能指针异常

    shared_ptr和new结合使用 一个shared_ptr默认初始化为一个空指针.我们也可以使用new返回的指针来初始化一个shared_ptr: shared_ptr<double> ...

  4. hihoCoder:#1079(线段树+离散化)

    题目大意:给n个区间,有的区间可能覆盖掉其他区间,问没有完全被其他区间覆盖的区间有几个?区间依次给出,如果有两个区间完全一样,则视为后面的覆盖前面的. 题目分析:区间可能很长,所以要将其离散化.但离散 ...

  5. 【BZOJ1004】【HNOI20008】cards

    看黄学长的代码才写出来的,sro_hzwer_orz 原题: 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给 ...

  6. Linux系统编程@进程管理(二)

    1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...

  7. java基础之:匿名内部类

    在java提高篇-----详解内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以 了解到匿名内部类的使用.匿名内部类要注意的事项.如何初 ...

  8. js获取ifram对象

    1.获取iframe对象 var doc=document.getElementById('frameId').contentWindow.document; //var doc=parent.doc ...

  9. windows的页自映射机制

    windows下由于启用了页机制,所有软件层面的地址操作都是VA,通过descriptor(base address(32bit))+offset得到的线性地址并不直接对应物理地址,而是经过页转换机构 ...

  10. C# TextBox 只能输入数字

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { TextBox txt = sender as TextBox ...