「NOI2016」問題解決の間隔レポート

「NOI2016」セクション

最近良い硬い思考ああ...

最初のセクション上の1までは2つのエンドポイントの差は、スキャン位置配列、各位置で維持回答、メンテナンス間隔配列データ構造の現在位置ではなく、維持に分割されます。

だから、あなたには、いくつかのプロパティを持っていないか、私はなぜ区間長の重みを持って来ると思いますが、自然を勉強したいです

だから、長い時間のインターバルの長さの性質を考える、私はそのようなゾーンが寄与が追加され、それにカウントが削除された場合にのみ、好きなものなど、いくつかの結論を、推測SB ...

自閉症の[すべて間違っています...

そして、どのようなキング・ジェームズの最大思うし、その後、間隔を尋ね、その後、私はその後、(実際には勝つためにツリーラインからの単調なキューは正の解である、私はそれがあったとは思いませんでした)単調ポイントキューをハングアップするために、各セグメントの木を見つけましたセルフクロージング

そして、完全に帝国の最大値と最小値を、と思うとにかく、唯一の\(N ^ 2 \)種、そして私たちは、最小値と最大値の間の間隔の長さをチェックする必要があり、その後、私たちはこれらの間隔の範囲を見て、より位置の値がない\ (M \)より大きな範囲と染色することができ、その後、最大値を問い合わせます

これは、ツリーの外に暴力を取ることができ、木のカバーは、上のようです

あなたがスキャンされている場合は最大最小はその後、その後移動し、二つのポインタを見つけたです\(O(n)と\) および定規からの借入は、あなただけの木のラインを維持することができ、尋ねるようなものです。


コード:

#include <cstdio>
#include <cctype>
#include <algorithm>
using std::max;
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
//#define gc() getchar()
template <class T>
void read(T &x)
{
    x=0;char c=gc();
    while(!isdigit(c)) c=gc();
    while(isdigit(c)) x=x*10+c-'0',c=gc();
}
void ckmin(int &x,int y){x=x<y?x:y;}
const int inf=0x3f3f3f3f;
const int N=5e5+10;
int n,m,k,saki[N<<1];
struct _toki
{
    int l,r,val;
    bool friend operator <(_toki a,_toki b){return a.val<b.val;}
}toki[N];
int mx[N<<3],tag[N<<3];
#define ls id<<1
#define rs id<<1|1
void pushdown(int id)
{
    if(tag[id])
    {
        mx[ls]+=tag[id],tag[ls]+=tag[id];
        mx[rs]+=tag[id],tag[rs]+=tag[id];
        tag[id]=0;
    }
}
void upt(int id,int L,int R,int l,int r,int d)
{
    if(r<L||l>R) return;
    if(l<=L&&R<=r)
    {
        mx[id]+=d;
        tag[id]+=d;
        return;
    }
    pushdown(id);
    int Mid=L+R>>1;
    upt(ls,L,Mid,l,r,d),upt(rs,Mid+1,R,l,r,d);
    mx[id]=max(mx[ls],mx[rs]);
}
int qry(int id,int L,int R,int l,int r)
{
    if(r<L||l>R) return 0;
    if(l<=L&&R<=r) return mx[id];
    pushdown(id);
    int Mid=L+R>>1;
    return max(qry(ls,L,Mid,l,r),qry(rs,Mid+1,R,l,r));
}
int main()
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    read(n),read(k);
    for(int i=1;i<=n;i++)
    {
        read(toki[i].l),read(toki[i].r);
        saki[++m]=toki[i].l,saki[++m]=toki[i].r;
        toki[i].val=toki[i].r-toki[i].l;
    }
    std::sort(saki+1,saki+1+m);
    m=std::unique(saki+1,saki+1+m)-saki-1;
    for(int i=1;i<=n;i++)
    {
        toki[i].l=std::lower_bound(saki+1,saki+1+m,toki[i].l)-saki;
        toki[i].r=std::lower_bound(saki+1,saki+1+m,toki[i].r)-saki;
    }
    std::sort(toki+1,toki+1+n);
    int l=1,r=1,ans=inf;
    while(r<=n)
    {
        upt(1,1,m,toki[r].l,toki[r].r,1);
        while(qry(1,1,m,toki[r].l,toki[r].r)>=k)
        {
            ckmin(ans,toki[r].val-toki[l].val);
            upt(1,1,m,toki[l].l,toki[l].r,-1);
            ++l;
        }
        ++r;
    }
    if(ans==inf) puts("-1");
    else printf("%d\n",ans);
    return 0;
}

2019年5月30日

おすすめ

転載: www.cnblogs.com/butterflydew/p/10950152.html