以上の2019頭の牛オフサマースクールキャンプ(七)中央値(範囲のセグメントツリー+離散点)を検索-E

トピックリンクします。https://ac.nowcoder.com/acm/contest/887/E

問題の意味:指定されたL [i]は、R [i]は、Lの各添加[i]は... R [i]は、この時点で算出された中央。

アイデア:範囲の数は1E9に添加するので、第1の離散使用することが考えられ、ここで範囲を示す点です。

 

 

プラス右の主な目的のセクションには、彼らの前に組み込まれた最後の要素の範囲は、それを理解する瞬間をシミュレートし、プロセスを最適化することです。

次いで左サブツリーで、または右サブツリーの左サブツリー十分クエリ内の要素の数ならば、各ノードに含まれる要素の数、プラス遅延マークのLazで表される数は、各時間クエリでツリーラインを維持しますクエリ。

コードを参照してください。

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;

typedef long long LL;
const int maxn=4e5+5;

struct node{
    int l,r,laz;
    LL sz;
}tr[maxn<<3];

int n;
LL X[maxn],Y[maxn],A1,A2,B1,B2,C1,C2,M1,M2;
vector<int> vc;

void build(int v,int l,int r){
    tr[v].l=l,tr[v].r=r;
    if(l==r){
        return;
    }
    int mid=(l+r)>>1;
    build(v<<1,l,mid);
    build(v<<1|1,mid+1,r);
}

void pushdown(int v){
    tr[v<<1].sz+=(vc[tr[v<<1].r+1]-vc[tr[v<<1].l])*tr[v].laz;
    tr[v<<1].laz+=tr[v].laz;
    tr[v<<1|1].sz+=(vc[tr[v<<1|1].r+1]-vc[tr[v<<1|1].l])*tr[v].laz;
    tr[v<<1|1].laz+=tr[v].laz;
    tr[v].laz=0;
}

void update(int v,int l,int r){
    if(l<=tr[v].l&&r>=tr[v].r){
        tr[v].sz+=(vc[tr[v].r+1]-vc[tr[v].l]);
        tr[v].laz+=1;
        return;
    }
    if(tr[v].laz) pushdown(v);
    int mid=(tr[v].l+tr[v].r)>>1;
    if(l<=mid) update(v<<1,l,r);
    if(r>mid) update(v<<1|1,l,r);
    tr[v].sz=tr[v<<1].sz+tr[v<<1|1].sz;
}

int query(int v,LL k){
    if(tr[v].l==tr[v].r){
        int tmp=tr[v].sz/(vc[tr[v].l+1]-vc[tr[v].l]);
        return vc[tr[v].l]+(k-1)/tmp;
    }
    if(tr[v].laz) pushdown(v);
    if(k<=tr[v<<1].sz) return query(v<<1,k);
    else return query(v<<1|1,k-tr[v<<1].sz);
}

int main(){
    scanf("%d",&n);
    scanf("%lld%lld%lld%lld%lld%lld",&X[1],&X[2],&A1,&B1,&C1,&M1);
    scanf("%lld%lld%lld%lld%lld%lld",&Y[1],&Y[2],&A2,&B2,&C2,&M2);
    for(int i=3;i<=n;++i){
        X[i]=(A1*X[i-1]%M1+B1*X[i-2]%M1+C1)%M1;
        Y[i]=(A2*Y[i-1]%M2+B2*Y[i-2]%M2+C2)%M2;
    }
    for(int i=1;i<=n;++i){
        ++X[i],++Y[i];
        if(X[i]>Y[i]) swap(X[i],Y[i]);
        vc.push_back(X[i]),vc.push_back(Y[i]+1);
    }
    sort(vc.begin(),vc.end());
    vc.erase(unique(vc.begin(),vc.end()),vc.end());
    LL sum=0;
    int cnt=vc.size();
    build(1,0,cnt-1);
    for(int i=1;i<=n;++i){
        sum+=Y[i]-X[i]+1;
        int x,y;
        x=lower_bound(vc.begin(),vc.end(),X[i])-vc.begin();
        y=lower_bound(vc.begin(),vc.end(),Y[i]+1)-vc.begin();
        update(1,x,y-1);
        printf("%d\n",query(1,(sum+1)>>1));
    }
    return 0;
}

 

おすすめ

転載: www.cnblogs.com/FrankChen831X/p/11349154.html
おすすめ