4383 bzoj [POI2015]砂漠

LINK:POI2015砂漠

タイトルの意味は、もはや数字の残りの部分よりも大きくなると可解性と出力ソリューションかどうかを判断するために述べられていません。

差制約モデルを考えてみましょう。インターバルの各側面が大きすぎてもので私たちも、暴力的な側面を行くことができないためにその建設セグメントツリー図の最適化を検討してください。

複雑:以来\(\和K \当量3 ×10 ^ 5 \) Klognのでアップポイントの各側面が許容範囲のエッジに作成する必要があるにもかかわらず。

そのようなエッジは厄介なことがあっても、出力Bを実行する状況B <= 1プログラムすることを> bは変化に> = B + 1に変換することができる方法を検討するための解決策を分析しません。

> = B + 1 Bの元の形は、少なくとも> = B + 1側に接続され、常に大ランspfa図ない表します。

避けられないので、何の解決リングがない場合でも、この絵の特殊な性質を与えられた。これは、非循環有向グラフです。

最後に、私たちは似た形の解を求めることができるDP topsort楽しみ、その後ソリューションを構築し、方法を検討します。

最後に、もちろん、また、適切な範囲かどうかを判断する必要があります。

const int MAXN=100010,maxn=2000010;
int n,m,v,flag,cnt,len,root;
int a[MAXN],f[maxn],q[maxn];
int lin[maxn],ver[maxn],nex[maxn],e[maxn],ru[maxn];
struct wy{int l,r;}t[MAXN<<2];
inline void add(int x,int y,int z)
{
    ver[++len]=y;
    nex[len]=lin[x];
    lin[x]=len;
    e[len]=z;
    ++ru[y];
}
inline void build(int &p,int l,int r)
{
    p=++cnt;
    if(l==r){add(p,l,0);return;}
    int mid=(l+r)>>1;
    build(l(p),l,mid);
    build(r(p),mid+1,r);
    add(p,l(p),0);add(p,r(p),0);
}
inline void change(int p,int l,int r,int L,int R,int x)
{
    if(L>R)return;
    if(L<=l&&R>=r){add(x,p,1);return;}
    int mid=(l+r)>>1;
    if(L<=mid)change(l(p),l,mid,L,R,x);
    if(R>mid)change(r(p),mid+1,r,L,R,x);
}
inline void topsort()
{
    int l=0,r=0;
    for(int i=1;i<=cnt;++i)
    {
        f[i]=INF;
        if(!ru[i])q[++r]=i;
    }
    while(++l<=r)
    {
        int x=q[l];
        if(f[x]<1){flag=1;return;}
        if(x<=n&&a[x])
        {
            if(f[x]<a[x]){flag=1;return;}
            else f[x]=a[x];
        }
        for(int i=lin[x];i;i=nex[i])
        {
            int tn=ver[i];
            f[tn]=min(f[tn],f[x]-e[i]);
            --ru[tn];if(!ru[tn])q[++r]=tn;
        }
    }
    for(int i=1;i<=cnt;++i)if(ru[i])flag=1;
}
int main()
{
    freopen("1.in","r",stdin);
    get(n);get(v);get(m);
    for(int i=1;i<=v;++i)
    {
        int x;
        get(x);get(a[x]);
        if(a[x]>INF)flag=1;
    }
    if(flag){puts("NIE");return 0;}
    cnt=n;build(root,1,n);
    rep(1,m,i)
    {
        int x,y,k,p;
        get(x);get(y);get(k);
        ++cnt;
        rep(1,k,j)
        {
            get(p);
            add(p,cnt,0);
            if(j==1){if(x<p)change(root,1,n,x,p-1,cnt);}
            else if(x+1!=p)change(root,1,n,x+1,p-1,cnt);
            x=p;
        }
        if(p<y)change(root,1,n,p+1,y,cnt);
    }
    topsort();
    if(flag){puts("NIE");return 0;}
    puts("TAK");
    rep(1,n,i)printf("%d ",f[i]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/chdy/p/12466623.html