题目大意:给定一个长度为n的正整数序列 a ,每个数都在1到
109
范围内
已知其中s个数,并给出m条信息,每条信息形如l,r,k以及接下来k个正整数,表示
a[l],a[l+1],...,a[r−1],a[r]
里这k个数中的任意一个都比任意一个剩下的r-l+1-k个数严格大
构造一组解或判断无解
题解:膜GXZ大爷
我的收获:常见操作
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
int n,s,m,tot;
int t,head[N];
int p[N],f[N],kn[N],xx[N],in[N];
queue<int> q;
struct edge{int to,nex,val;}e[N<<2];
void add(int u,int v,int w){in[v]++,e[t].to=v,e[t].nex=head[u],e[t].val=w,head[u]=t++;}
struct SegmentTree{
#define ls x<<1
#define rs x<<1|1
#define lson l,mid,x<<1
#define rson mid+1,r,x<<1|1
#define root 1,n,1
void build(int l,int r,int x)
{
if(l==r){p[l]=x;return ;}
int mid=l+r>>1;
build(lson),build(rson);
add(ls,x,0),add(rs,x,0);
}
void update(int L,int R,int ot,int l,int r,int x)
{
if(L<=l&&r<=R){add(x,ot,0);return ;}
int mid=l+r>>1;
if(L<=mid) update(L,R,ot,lson);
if(R>mid) update(L,R,ot,rson);
}
}T;
void work()
{
for(int i=1;i<=tot;i++) if(!in[i]) f[i]=max(f[i],1),q.push(i);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=e[i].nex){
int v=e[i].to;
f[v]=max(f[v],f[u]+e[i].val),in[v]--;
if(kn[v]&&f[v]>kn[v]){puts("NIE\n");return ;}
if(!in[v]) q.push(v);
}
}
for(int i=1;i<=n;i++) if(!f[p[i]]||f[p[i]]>1e9){puts("NIE");return ;}
puts("TAK");
for(int i=1;i<=n;i++) printf("%d%c",f[p[i]],i<n?' ':'\n');
}
void init()
{
int c,d,l,r,k;memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&s,&m);T.build(root);tot=n<<2;
while(s--) scanf("%d%d",&c,&d),f[p[c]]=kn[p[c]]=d;
while(m--){
scanf("%d%d%d",&l,&r,&k),xx[0]=l-1,xx[k+1]=r+1,tot++;
for(int i=1;i<=k;i++) scanf("%d",&xx[i]),add(tot,p[xx[i]],1);
for(int i=0;i<=k;i++) if(xx[i+1]-xx[i]>1) T.update(xx[i]+1,xx[i+1]-1,tot,root);
}
}
int main()
{
init();
work();
return 0;
}