zoukankan      html  css  js  c++  java
  • hdu 6621 主席树+二分

    题意:给一个数组a,每次询问,给定L, R, p, K,求[ L , R ] 中的数与p做差的绝对值的第k小。

    思路:对数组a建立主席树(不用离散化),对于每次询问,二分答案,如果 [ L , R ] 区间中的 [ p - mid , p + mid ] 范围内的数大于K,则说明二分的答案偏大,需要缩小区间;如果等于K,也需要缩小,因为要找到精确的值;小于K则需要放大区间。(可以画数轴理解)

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+10;
     4 const int N=1e6;
     5 struct node{
     6     int val,l,r;
     7 }tree[maxn*22];
     8 int root[N];
     9 int tot;
    10 int n,m;
    11 void update(int &p,int x,int l,int r,int rt){
    12     p=++tot;
    13     tree[p]=tree[rt];
    14     tree[p].val++;
    15     if(l==r) return;
    16     int mid=(l+r)>>1;
    17     if(x<=mid) update(tree[p].l,x,l,mid,tree[rt].l);
    18     if(x>mid) update(tree[p].r,x,mid+1,r,tree[rt].r);
    19 }
    20 int query(int u,int v,int x,int y,int l,int r){
    21     if(x<=l&&r<=y){
    22         return tree[v].val-tree[u].val;
    23     }
    24     int ans=0;
    25     int mid=(l+r)>>1;
    26     if(x<=mid) ans+=query(tree[u].l,tree[v].l,x,y,l,mid);
    27     if(y>mid) ans+=query(tree[u].r,tree[v].r,x,y,mid+1,r);
    28     return ans;
    29 }
    30 int solve(int L,int R,int x,int y){
    31     x=max(x,1);
    32     y=min(y,N);
    33     return query(root[L-1],root[R],x,y,1,N);
    34 }
    35 int main()
    36 {
    37     int T;
    38     scanf("%d",&T);
    39     while(T--){
    40         tot=0;
    41         scanf("%d%d",&n,&m);
    42         for(int i=1;i<=n;i++){
    43             int x;
    44             scanf("%d",&x);
    45             update(root[i],x,1,N,root[i-1]); 
    46         }
    47         int ans=0;
    48         for(int i=1;i<=m;i++){
    49             int L,R,p,K;
    50             scanf("%d%d%d%d",&L,&R,&p,&K);
    51             L^=ans,R^=ans,p^=ans,K^=ans;
    52             int l=0,r=N,mid;
    53             while(r>=l){
    54                 mid=(l+r)>>1;
    55                 if(solve(L,R,p-mid,p+mid)>=K)
    56                     r=mid-1;
    57                 else l=mid+1;
    58             }
    59             ans=l;
    60             printf("%d
    ",ans);
    61         }
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    Javascript 返回上一页
    html中link和import方式导入CSS文件的区别
    Leecode no.76 最小覆盖子串
    Leecode no.344 反转字符串
    Leecode no.167 两数之和 II 输入有序数组
    Leecode no.567 字符串的排列
    遍历目录和文件信息
    JAVASCRIPT显示农历的日历
    asp.net上传图片加水印(c#)
    asp.net XML操作类
  • 原文地址:https://www.cnblogs.com/--HY--/p/13495073.html
Copyright © 2011-2022 走看看