Jzoj3163 排列
给你M个对1到N的排列的特征,特征有两种:
1 x y v:排列的第x个数到第y个数之间的最大值为v
2 x y v:排列的第x个数到第y个数之间的最小值为v
要求你还原出这个排列(N<=200,M<=40000)
刷水题有利于身心健康
但你还不是不会做?额这
想必许多人看完题目就知道怎么做了吧,才200直接二分图匹配就搞定了啊,O(NM)建图没问题
(另外,2014年那时候还没有匈牙利算法吗?为什么好多人直接写暴力网络流还跑的飞快)
#pragma GCC opitmize("O3")
#pragma G++ opitmize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char s[210][210];
int n,m,f[210],v[210];
inline bool match(int x){
for(int j=1;j<=n;++j)
if(s[x][j]&&!v[j]){
v[j]=1;
if(!f[j]||match(f[j])){
f[j]=x; return 1;
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
memset(s,1,sizeof s);
for(int o,l,r,v;m--;){
scanf("%d%d%d%d",&o,&l,&r,&v);
if(o==1)
for(int i=l;i<=r;++i) memset(s[i]+v+1,0,n-v);
else for(int i=l;i<=r;++i) memset(s[i],0,v);
for(int i=1;i<l;++i) s[i][v]=0;rt
for(int i=n;i>r;--i) s[i][v]=0;
}
for(int i=1;i<=n;++i){
memset(v,0,sizeof v);
if(!match(i)) return 0&puts("-1");
}
for(int i=1;i<=n;++i) v[f[i]]=i;
for(int i=1;i<=n;++i) printf("%d ",v[i]);
}