• 2019牛客暑期多校训练营(第七场) E 线段树+离散化


    题目传送门

    题意:按照一定的公式给出若干个$<l,r>$,每次往一个序列中加上l到r的数字,并输出中位数。

    思路:需要将每个$区间$离散化,比如把$[1,2]$变成$[1,3)$,也就是$[1,2)$和$[2,3)$,这样做才能完整的表达区间,否则如[2,2]这样的区间就会出现问题。

      所以我们将每一个$[l,r+1)$离散化,设$(x)$代表x离散化后的数字,每次更新的时候,右区间应该是$(r+1)-1$。比如原来只有一个区间$[2,3]$,我们表示成$[2,4)$,离散化后我们更新的区间是$[1,1]$,加的数字的个数是$ve[2]-ve[1]$,ve是原数组。

      查询和更新思路一样。

    #include<bits/stdc++.h>
    #define clr(a,b) memset(a,b,sizeof(a))
    #define pb(a)  push_back(a)
    #define rep(i,x,n) for(int i=x;i<=n;++i)
    #define dep(i,n,x) for(int i=n;i>=x;--i)
    using namespace std;
    typedef long long ll;
    int n,m;
    const int inf=0x3f3f3f3f;
    const int maxn=4e5+10;
    ll x[maxn],y[maxn],A1,B1,C1,M1,A2,B2,C2,M2;
    vector<ll >ve;
    ll sz[maxn<<3],lazy[maxn<<3];
    void add(int o,int l,int r,ll f){
        sz[o]+=(ve[r+1]-ve[l])*f;
        lazy[o]+=f;
    }
    void pushdown(int o,int l,int r){
        if(!lazy[o]||l==r)return;
        int mid=(l+r)>>1;
        add(o<<1,l,mid,lazy[o]);
        add(o<<1|1,mid+1,r,lazy[o]);
        lazy[o]=0;
    }
    void update(int o,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            add(o,l,r,1);
            return;
        }
        int mid=(l+r)>>1;
        pushdown(o,l,r);
        if(ql<=mid)update(o<<1,l,mid,ql,qr);
        if(mid<qr)update(o<<1|1,mid+1,r,ql,qr);
        sz[o]=sz[o<<1]+sz[o<<1|1];
    }
    
    ll query(int o,int l,int r,int num){
        if(l==r){
            ll tot=sz[o]/(ve[l+1]-ve[l]);
            return ve[l]+(num-1)/tot;
        }
        pushdown(o,l,r);
        int mid=(l+r)>>1;
        if(sz[o<<1]>=num)return query(o<<1,l,mid,num);
        return query(o<<1|1,mid+1,r,num-sz[o<<1]);
    }
    
    
    int main(){
        int n;
        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);
           rep(i,3,n){
            x[i]=(A1*x[i-1]+B1*x[i-2]+C1)%M1;
            y[i]=(A2*y[i-1]+B2*y[i-2]+C2)%M2;
        }
        
        rep(i,1,n){
            x[i]++,y[i]++;
            if(x[i]>y[i]) swap(x[i],y[i]);
            ve.push_back(x[i]); ve.push_back(y[i]+1);
        }
        sort(ve.begin(),ve.end());
        ve.erase(unique(ve.begin(),ve.end()),ve.end());
        int cnt=ve.size();
        rep(i,1,n){
            
              x[i]=lower_bound(ve.begin(),ve.end(),x[i])-ve.begin();
            y[i]=lower_bound(ve.begin(),ve.end(),y[i]+1)-ve.begin();
            update(1,0,cnt,x[i],y[i]-1);
            printf("%lld
    ",query(1,0,cnt,(sz[1]+1)/2));
        }
    }
  • 相关阅读:
    Unity WebGL打包发布报错
    Makefile:4: *** missing separator. Stop.
    Unity使用VSCode没有代码提示/代码无法折叠
    Unreal Engine is exiting due to D3D device being lost
    使用Doxygen生成UE4的chm格式API文档
    'UTextRenderComponent::SetText': Passing text as FString is deprecated, please use FText instead (likely via a LOCTEXT)
    f4v格式视频播放失败
    Unity自定义Button组件Transition
    mysql安装步骤
    ansible 安装
  • 原文地址:https://www.cnblogs.com/mountaink/p/11327719.html
Copyright © 2020-2023  润新知