zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第七场)-E Find the median (线段树+离散化 区间为点)

    题目链接:https://ac.nowcoder.com/acm/contest/887/E

    题意:给出L[i],R[i],每次添加L[i]...R[i],求出此时的中位数。

    思路:因为添加的数范围为1e9,首先想到要用离散化,这里是用一个点来表示一个区间。

     

    将右区间加一的主要目的是优化处理,将区间最后一个元素并入到前面,自己模拟一下就能明白啦。

    然后用线段树维护每个节点所包含的元素个数,用懒惰标记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
    ",query(1,(sum+1)>>1));
        }
        return 0;
    }
  • 相关阅读:
    forEach 获取下标信息
    js select选择框回显 当value是汉字时
    java 大写字符串字符串转成小写驼峰格式
    关于too many open files解决方案
    mysql 判断区间是否存在交集和并集
    http 请求拼接多个请求参数
    Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project jic-member: There are test failures.
    用dubbo时遇到的一个序列化的坑 xxxServiceImpl must implement java.io.Serializable
    django的分页器
    Django-form组件和ModelForm组件
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11349154.html
Copyright © 2011-2022 走看看