【题解】Informacije [COCI2012]
【题解】Informacije [COCI2012]
传送门:官方题面
【题目描述】
有一个长度为 \(n\) 的 序列 \(a\)(由 \([1,n]\) 中的数组成,且每个数只会出现一次),现给出两个整数 \(n,m\) 和 \(m\) 个关于 \(a\) 的描述,格式如下:
\(1\ l\ r\ v\) 表示 \(max\{a[l],a[l+1]...a[r]\}=v\),
\(2\ l\ r\ v\) 表示 \(min\{a[l],a[l+1]...a[r]\}=v\)。
请输出一个满足上面 \(m\) 个描述的序列,如果多种答案,输出任意一种,无解则输出 \(-1\)。
【样例】
样例输入:
3 2
1 1 1 1
2 2 2 2
样例输出:
1 2 3
样例输入:
4 2
1 1 1 1
2 3 4 1
样例输出:
-1
样例输入:
5 2
1 2 3 3
2 4 5 4
样例输出:
1 2 3 4 5
【数据范围】
\(100 \%:\) \(1 \leqslant n \leqslant 200,\) \(0 \leqslant m \leqslant 40000\)
【分析】
\(n \leqslant 200\),一开始只是觉得可以写 \(n^3\) 的算法,比如矩阵乘法之类的,但看到 \(m \leqslant 40000\) 时,瞬间想到建一张完全图跑图论。事实证明这一直觉是正确的。
用 \(pan[i][j]\) 表示整数 \(i\) 是否可以填在 \(j\) 这个位置(只需要满足给出的 \(m\) 个条件即可)。
如果 \(pan[i][j]\) 为 \(1\),那么 \(i\) 向 \(j\) 连一条有向边,然后跑一遍二分图最大匹配,\(match\) 数组即为答案。
匈牙利算法的时间复杂度为:\(O(|V|*|E|)\),其中 \(|E| \leqslant |V|^2\),\(200\) 个点的完全图完全不是问题。
如何求 \(pan\) 数组?
最开始 \(yy\) 了一种 \(mn\) 的预处理方法:
\((1).\) \(Lw[x],Rw[x]\) 分别表示整数 \(x\) 必须要放的位置所在区间左右端点。
对于所有的 \(l,r,v\),\(Lw[v]=max\{l,Lw[v]\},Rw[v]=min\{r,Rw[v]\}\)。
\((2).\) \(Ls[i],Rs[i]\) 分别表示位置 \(i\) 可放置的整数范围。
对于 \(1,l,r,v\),\(Rs[i]=min\{v,Rs[i]\} (i \in [l,r])\),
对于 \(2,l,r,v\),\(Ls[i]=max\{v,Ls[i]\} (i \in [l,r])\)。
但仔细想想觉得不太对,所以就改成了 \(mn^2\) 的暴力枚举,本以为会超时,结果加了剪枝后居然轻松跑过了。
后来发现官方题解给的就是 \(mn\) 的做法,而且和我之前想的一模一样。。。
【Code】
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define Re register int
using namespace std;
const int N=203,M=40003,inf=2e9;
int n,m,op[M],L[M],R[M],val[M],pan[N][N];
int o,ans,vis[N],head[N],match[N];
struct QAQ{int to,next;}a[N*N];
inline void add(Re x,Re y){a[++o].to=y,a[o].next=head[x],head[x]=o;}
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
inline int judge(Re i,Re L,Re R){//判断在[L,R]这个区间内是否有1
for(Re j=L;j<=R;++j)if(pan[i][j])return 1;
return 0;
}
inline void add_(Re i,Re L,Re R){//将[L,R]全部变为0
for(Re j=L;j<=R;++j)pan[i][j]=0;
}
inline void add(Re i,Re L,Re R){//将[L,R]以外的全部变为0
for(Re j=1;j<L;++j)pan[i][j]=0;
for(Re j=R+1;j<=n;++j)pan[i][j]=0;
}
inline void Print(){
for(Re i=1;i<=n;++i){
printf("pan[%d]: ",i);
for(Re j=1;j<=n;++j)if(pan[i][j])printf("%d ",j);
puts("");
}
puts("");
}
inline int sakura(){
for(Re i=1;i<=m;++i){
if(op[i]>1){//L[i]~R[i]的最小值为val[i]
if(!judge(val[i],L[i],R[i]))return 0;
add(val[i],L[i],R[i]);
for(Re j=1;j<val[i];++j){//比val小的数
Re flag1=judge(j,1,L[i]-1),flag2=judge(j,R[i]+1,n);
if(!flag1&&!flag2)return 0;//如果没有可放的位置就直接return
else if(flag1&&!flag2)add(j,1,L[i]-1);//删掉左边
else if(flag2&&!flag1)add(j,R[i]+1,n);//删掉右边
else add_(j,L[i],R[i]);//删掉左右两边
}
}
else{//L[i]~R[i]的最大值为val[i]
if(!judge(val[i],L[i],R[i]))return 0;
add(val[i],L[i],R[i]);
for(Re j=val[i]+1;j<=n;++j){//比val大的数
Re flag1=judge(j,1,L[i]-1),flag2=judge(j,R[i]+1,n);
if(!flag1&&!flag2)return 0;
else if(flag1&&!flag2)add(j,1,L[i]-1);
else if(flag2&&!flag1)add(j,R[i]+1,n);
else add_(j,L[i],R[i]);
}
}
}
return 1;//最后还要return 1
}
inline int dfs(Re x){
for(Re i=head[x],to;i;i=a[i].next)
if(!vis[to=a[i].to]){
vis[to]=1;
if(!match[to]||dfs(match[to])){
match[to]=x;return 1;
}
}
return 0;
}
int main(){
// freopen("informacije.in","r",stdin);
// freopen("informacije.out","w",stdout);
in(n),in(m);
for(Re i=1;i<=m;++i)in(op[i]),in(L[i]),in(R[i]),in(val[i]);
for(Re i=1;i<=n;++i)
for(Re j=1;j<=n;++j)
pan[i][j]=1;
if(!sakura())puts("-1");
else{
// Print();
for(Re i=1;i<=n;++i)
for(Re j=1;j<=n;++j)
if(pan[i][j])add(i,j);
for(Re i=1;i<=n;++i){
memset(vis,0,sizeof(vis));
if(!dfs(i))return !puts("-1");
}
for(Re i=1;i<=n;++i)printf("%d ",match[i]);
}
fclose(stdin);
fclose(stdout);
return 0;
}
【题解】Informacije [COCI2012]的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- Spring Cloud Alibaba基础教程:Sentinel Dashboard同步Apollo存储规则
在之前的两篇教程中我们分别介绍了如何将Sentinel的限流规则存储到Nacos和Apollo中.同时,在文末的思考中,我都指出了这两套整合方案都存在一个不足之处:不论采用什么配置中心,限流规则都只能 ...
- node-sass安装失败处理办法
参考: https://npm.taobao.org/mirrors https://lzw.me/a/node-sass-install-helper.html 设置环境变量安装 SASS_BINA ...
- Java匹马行天下之学编程的起点——高级语言大锅烩
学编程的起点——高级语言大锅烩 前言: 学知识前总想说点鸡汤,想喝的朋友就看看,不想喝的就直接看干货吧,就当鸡汤是给我自己喝的. 前段时间在网上看了一句话感觉挺触动我的,我做个分享: 如果你觉得你的祖 ...
- 杂牌机搞机之旅最终章————刷入Xposed框架
杂牌机搞机之旅最终章----刷入Xposed框架 recovery移植不成功,没办法,挂载分区好像挂载不上,所以,刷入magisk如果卡在开机屏,只能线刷解决..心累.. 所以,折腾完XPosed框架 ...
- 自定义Visual Studio调试器中的对象显示方式
你有没有盯着调试器窗口中的对象,并希望你可以通过其他类型的东西来查看这些对象?我当然有!扩展项目以确定每个人的身份可能会非常快速.理想情况下,通过特定的属性值快速定位它们会很棒.对我们来说幸运的是,V ...
- Python笔记:设计模式之模板方法模式
此模式通过一个模板方法来定义程序的框架或算法,通常模板方法定义在基类中,即原始的模板,然后子类就可以根据不同的需要实现或重写模板方法中的某些算法步骤或者框架的某部分,最后达到使用相同模板实现不同功能的 ...
- JVM垃圾回收器原理及使用介绍
JVM垃圾回收器原理及使用介绍 垃圾收集基础 引用计数法(Reference Counting) 标记-清除算法(Mark-Sweep) 复制算法(Copying) 标记-压缩算法(Mark-Comp ...
- FCC---Learn How Bezier Curves Work---定义坐标轴点的值,影响斜率,改变速度。具体调试换值既可以体会
The last challenge introduced the animation-timing-function property and a few keywords that change ...
- Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例
一.项目简述 taro-chatroom是基于Taro多端实例聊天项目,运用Taro+react+react-redux+taroPop+react-native等技术开发的仿微信App界面聊天室,实 ...
- Javascript中的几种函数
(1)普通函数:这种函数是我们日常使用中用的最多的,用function关键字定义的函数.这也是符合多种语言定义的. function foo(){ // code } (2)箭头函数:用=>运算 ...