题意:有个n长序列,然后有m个事实,为ll,rr子串是不降的,或者是有降的。冲突输出NO,否则构造一个。
先离线,挑出所有不降的在[ll+1,rr]标记为1。然后有降的查询如果全是1,那么输出NO。否则第一个为n,遇到1,a(i)=a(i-1),遇到0,a(i)=a(i-1)-1。
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> #include <unordered_set> #define mkp make_pair using namespace std; const double EPS=1e-8; typedef long long lon; typedef pair<lon,lon> pii ; const lon SZ=100010,SSZ=0,APB=26,INF=0x7FFFFFF,mod=1000000007; lon n,m,ans[SZ]; bool vst[SZ]; struct nd{ int type,ll,rr; nd(int a=0,int b=0,int c=0):type(a),ll(b),rr(c){} }; nd in[SZ]; void init() { cin>>n>>m; for(int i=1;i<=m;++i) { int type,ll,rr; cin>>type>>ll>>rr; in[i]=nd(type,ll,rr); if(type==1)for(int j=ll+1;j<=rr;++j)vst[j]=1; } for(int i=1;i<=m;++i) { int type,ll,rr; type=in[i].type; ll=in[i].ll,rr=in[i].rr; if(type==0) { bool ok=0; for(int j=ll+1;j<=rr;++j) { if(!vst[j])ok=1; } if(!ok) { cout<<"NO"<<endl; return; } } } cout<<"YES"<<endl; ans[1]=n; for(int i=2;i<=n;++i) { if(vst[i])ans[i]=ans[i-1]; else ans[i]=ans[i-1]-1; } for(int i=1;i<=n;++i) { if(i!=1)cout<<" "; cout<<ans[i]; } cout<<endl; } void work() { } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); //lon casenum; //cin>>casenum; //for(lon tim=1;tim<=casenum;++tim) { init(); work(); } return 0; }
codeforces 1187c C. Vasya And Array
原文:https://www.cnblogs.com/gaudar/p/11521581.html