题意
题目链接。
给定
解析
考虑记
记
由于要输出方案,线段树改成 pair,分别存答案和产生这个答案的串即可。
代码
#include<bits/stdc++.h> #define pi pair<int,int> #define fi first #define se second #define mk make_pair #define ls x<<1 #define rs x<<1|1 using namespace std; const int N=3e5+5; pi tr[N<<3],tag[N<<3]; int n,m,pre[N],b[N<<1],cnt,mx; int ans,ansp; vector<pi> vec[N]; inline pi Max(pi x,pi y){ if(x.fi>y.fi) return x; return y; } inline void pushdown(int x){ if(!tag[x].fi) return; tr[ls]=tag[x],tr[rs]=tag[x]; tag[ls]=tag[x],tag[rs]=tag[x]; tag[x]=mk(0,0); } inline void pushup(int x){ tr[x]=Max(tr[ls],tr[rs]); } inline pi query(int x,int l,int r,int L,int R){ if(l>=L&&r<=R) return tr[x]; int mid=(l+r)>>1; pushdown(x); if(L<=mid&&R>mid) return Max(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R)); if(L<=mid) return query(ls,l,mid,L,R); return query(rs,mid+1,r,L,R); } inline void modify(int x,int l,int r,int L,int R,pi k){ if(l>=L&&r<=R){tr[x]=k;tag[x]=k;return;} int mid=(l+r)>>1; pushdown(x); if(L<=mid) modify(ls,l,mid,L,R,k); if(R>mid) modify(rs,mid+1,r,L,R,k); pushup(x); } bool vis[N]; int main(){ scanf("%d%d",&n,&m); for(int i=1,x,l,r;i<=m;i++){ scanf("%d%d%d",&x,&l,&r); vec[x].push_back(mk(l,r)); b[++cnt]=l;b[++cnt]=r; } sort(b+1,b+1+cnt); cnt=unique(b+1,b+1+cnt)-b-1; for(int i=1;i<=n;i++){ for(auto &x:vec[i]){ x.fi=lower_bound(b+1,b+1+cnt,x.fi)-b; x.se=lower_bound(b+1,b+1+cnt,x.se)-b; } }//离散化 for(int i=1;i<=n;i++){ mx=-1; for(auto x:vec[i]){//求当前串的答案 pi t=query(1,1,cnt,x.fi,x.se); if(t.fi>mx){mx=t.fi;pre[i]=t.se;} } if(mx+1>ans){//更新全局答案 ans=mx+1; ansp=i; } for(auto x:vec[i]){//更新对应位置的答案 pi t=mk(mx+1,i); modify(1,1,cnt,x.fi,x.se,t); } } printf("%d\n",n-ans); for(int i=ansp;i;i=pre[i]) vis[i]=1; for(int i=1;i<=n;i++){ if(!vis[i]) printf("%d ",i); } return 0; }
掉大分,哈哈。