ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r-1],a[r]里这k个数中的任意一个都比任意一个剩下的r-l+1-k个数大(严格大于,即没有等号)。
请任意构造出一组满足条件的方案,或者判断无解。

Input

第一行包含三个正整数n,s,m(1<=s<=n<=100000,1<=m<=200000)。
接下来s行,每行包含两个正整数p[i],d[i](1<=p[i]<=n,1<=d[i]<=10^9),表示已知a[p[i]]=d[i],保证p[i]递增。
接下来m行,每行一开始为三个正整数l[i],r[i],k[i](1<=l[i]<r[i]<=n,1<=k[i]<=r[i]-l[i]),接下来k[i]个正整数x[1],x[2],...,x[k[i]](l[i]<=x[1]<x[2]<...<x[k[i]]<=r[i]),表示这k[i]个数中的任意一个都比任意一个剩下的r[i]-l[i]+1-k[i]个数大。Σk <= 300,000

Output

若无解,则输出NIE。
否则第一行输出TAK,第二行输出n个正整数,依次输出序列a中每个数。

对大小关系用有向边表示,通过拓扑排序可以构造出一组可行解,由于直接连边边数过大,需要用线段树优化建图
 
#include<cstdio>
char buf[10000007],*ptr=buf-1;
int _(){
    int x=0,c=*++ptr;
    while(c<48)c=*++ptr;
    while(c>47)x=x*10+c-48,c=*++ptr;
    return x;
}
bool ed[1000007];
int n,s,m,mx=1,m2;
int v[1000007],in[1000007],vp,q[1000007],ql=0,qr=0;
int es[12000007][2],e0[1000007],ep=2;
void ae(int a,int b){
    es[ep][0]=b;es[ep][1]=e0[a];e0[a]=ep++;
    ++in[b];
}
void ins(int l,int r,int a){
    if(l<=r)
    for(l+=mx-1,r+=mx+1;l^r^1;l>>=1,r>>=1){
        if(~l&1)ae(a,l^1);
        if(r&1)ae(a,r^1);
    }
}
int main(){
    fread(buf,1,sizeof(buf),stdin);
    n=_();s=_();m=_();
    while(mx<n+3)mx<<=1;
    while(s--){
        int x=_();
        v[mx+x]=_();
        ed[mx+x]=1;
    }
    for(int i=1;i<mx;++i)ae(i,i<<1),ae(i,i<<1^1);
    m2=vp=mx<<1;
    while(m--){
        int l=_(),r=_(),k=_();
        for(int i=0,x;i<k;++i){
            x=_();
            ae(mx+x,vp);
            ins(l,x-1,vp);
            l=x+1;
        }
        ins(l,r,vp++);
    }
    for(int i=1;i<vp;++i)if(!v[i])v[i]=1000000000;
    q[++qr]=1;
    while(ql!=qr){
        int w=q[++ql];
        if(w>=m2)--v[w];
        if(v[w]<1)return puts("NIE"),0;
        for(int i=e0[w];i;i=es[i][1]){
            int u=es[i][0];
            if(v[u]>v[w]){
                if(ed[u])return puts("NIE"),0;
                else v[u]=v[w];
            }
            if(!--in[u])q[++qr]=u;
        }
    }
    if(qr+1!=vp)return puts("NIE"),0;
    puts("TAK");
    for(int i=1;i<=n;++i)printf("%d ",v[i+mx]);
    return 0;
}

 

posted on 2017-02-19 23:18  nul  阅读(510)  评论(0编辑  收藏  举报