• 2019牛客多校第七场 E.Find the median


    传送:https://ac.nowcoder.com/acm/contest/887/E

    题意:

    每次给数组插入区间$[L_i,R_i]$内的所有数,每操作一次查询中位数。

    分析:

    首先考虑暴力做法。就是对于一个数组,查询中位数的话,需要知道当前数组的大小$sum$,那么中位数的位置就是$(sum-1)/2$。

    对于多次插入,多次查询的问题,需要数据结构维护答案。

    考虑用线段树维护。线段树维护对于区间$[l,r]$内出现数的个数,同时需要$tag$标记当前区间更新次数。

    具体做法:

    对于区间$[L_i,R_i]$,首先需要离散化区间,存到$bb$数组再建线段树。这里有一个小技巧,建树的时候将右界扩大1,那么查询的时候长度直接就是$tree[root].r-tree[root].l$。

    对于每次的更新区间$[xx,yy]$,标记$tree[root].tag++$,以及$tree[root].num+=(bb[yy]-bb[xx])$。相当于对于每一个线段树的节点,维护了$bb[tree[root].l]--bb[tree[root].r-1]$内数字的个数。这里没有$tree[root].r$的原因是只是为了方便$update$和$query$时计算,这个节点的数字维护在同一级的右半个子树内。

    每添加一个区间$[xx,yy]$,插入总数组的数字个数增加了$bb[yy]-bb[xx]$(因为我们的$yy$本身就是$右界+1$了),中位数的位置$res$已经知道,那么在线段树内查询答案。如果左子树的个数$>=res$,就在左子树查询答案;否则就在右子树内查询第$res-tree[root<<1].num$个即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=4e5+10;
     5 struct node{
     6     int l,r;ll num;int tag;
     7 }tree[maxn<<3];
     8 int bb[maxn*2],X[maxn],Y[maxn],L[maxn],R[maxn];
     9 void build(int root,int l,int r){
    10     tree[root].l=l;tree[root].r=r;
    11     tree[root].num=0; tree[root].tag=0;
    12     if (l+1==r) return ;
    13     int mid=(l+r)>>1;
    14     build(root<<1,l,mid);
    15     build(root<<1|1,mid,r);
    16 }
    17 void pushdown(int root){
    18     if (tree[root].tag==0) return ;
    19     if (tree[root].l+1==tree[root].r) return ;
    20     tree[root<<1].tag+=tree[root].tag;
    21     tree[root<<1].num+=1ll*tree[root].tag*(bb[tree[root<<1].r]-bb[tree[root<<1].l]);
    22     tree[root<<1|1].tag+=tree[root].tag;
    23     tree[root<<1|1].num+=1ll*tree[root].tag*(bb[tree[root<<1|1].r]-bb[tree[root<<1|1].l]);
    24     tree[root].tag=0;
    25 }
    26 void pushup(int root){
    27     if (tree[root].l+1==tree[root].r) return ;
    28     tree[root].num=tree[root<<1].num+tree[root<<1|1].num;
    29 }
    30 void update(int root,int xx,int yy){
    31     if (xx==tree[root].l && tree[root].r==yy){
    32         tree[root].num+=bb[yy]-bb[xx];
    33         tree[root].tag++;
    34         return ;
    35     }
    36     pushdown(root);
    37     int mid=(tree[root].l+tree[root].r)>>1;
    38     if (yy<=mid) update(root<<1,xx,yy);
    39     else if (xx>=mid) update(root<<1|1,xx,yy);
    40     else{
    41         update(root<<1,xx,mid);
    42         update(root<<1|1,mid,yy);
    43     }
    44     pushup(root);
    45 }
    46 ll query(int root,ll res){
    47     if (tree[root].l+1==tree[root].r){
    48         ll tmp=tree[root].num/(bb[tree[root].r]-bb[tree[root].l]);
    49         return bb[tree[root].l]+(res-1)/tmp;
    50     }
    51     pushdown(root);
    52     if (res<=tree[root<<1].num) return query(root<<1,res);
    53     else return query(root<<1|1,res-tree[root<<1].num);
    54 }
    55 int main(){
    56     int n;scanf("%d",&n);int A1,A2,B1,B2,C1,C2,M1,M2;
    57     scanf("%d%d%d%d%d%d",&X[1],&X[2],&A1,&B1,&C1,&M1);
    58     scanf("%d%d%d%d%d%d",&Y[1],&Y[2],&A2,&B2,&C2,&M2);
    59     for (int i=3;i<=n;i++) X[i]=(1ll*A1*X[i-1]+1ll*B1*X[i-2]+C1)%M1;
    60     for (int i=3;i<=n;i++) Y[i]=(1ll*A2*Y[i-1]+1ll*B2*Y[i-2]+C2)%M2;
    61     int tot=0;
    62     for (int i=1;i<=n;i++){
    63         L[i]=min(X[i],Y[i])+1,R[i]=max(X[i],Y[i])+1; R[i]++;
    64         bb[++tot]=L[i]; bb[++tot]=R[i];
    65     }
    66     sort(bb+1,bb+1+tot);
    67     int totn=unique(bb+1,bb+1+tot)-(bb+1);
    68     for (int i=1;i<=n;i++){
    69         L[i]=lower_bound(bb+1,bb+1+totn,L[i])-bb;
    70         R[i]=lower_bound(bb+1,bb+1+totn,R[i])-bb;
    71     }
    72     build(1,1,totn);
    73     ll sum=0;
    74     for (int i=1;i<=n;i++){
    75         update(1,L[i],R[i]);  //l--r+1
    76         sum+=(bb[R[i]]-bb[L[i]]);// len=r-l+1 
    77         ll res=(sum+1)/2;
    78         ll ans=query(1,res);
    79         printf("%lld
    ",ans);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    TypeScript的泛型接口 泛型类接口
    typeScript中的泛型
    Node.js Tools 1.2 for Visual Studio 2015 released
    无法访问 IIS 元数据库。您没有足够的特权访问计算机上的 IIS 网站
    jexus jws 安装
    coreos安装
    Visual Studio Code 怎么支持中文
    docker管理shipyard中文版v3.0.2更新
    docker和shipyard使用问题
    DESCryptoServiceProvider
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11327322.html
Copyright © 2020-2023  润新知