zoukankan      html  css  js  c++  java
  • HDU 6621 K-th Closest Distance(二分、主席树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6621

    题意

    查询在区间[L,R]内离p第k近的距离,强制在线。

    题解

    二分答案,建立主席树。

    sum[i]表示在i节点管辖的这个区间[l,r]有多少个数的前缀和。

    看博客没看懂,看队友代码学会了主席树,还有谁。

    代码风格参考自ccsu_cat

     1 #define bug(x) cout<<#x<<" is "<<x<<endl
     2 #define IO std::ios::sync_with_stdio(0)
     3 #include <bits/stdc++.h>
     4 #define iter ::iterator
     5 using namespace  std;
     6 typedef long long ll;
     7 typedef pair<ll,ll>P;
     8 typedef pair<P,P>P1;
     9 #define mk make_pair
    10 #define pb push_back
    11 #define se second
    12 #define fi first
    13 const int N=1e5+5;
    14 ll mod=998244353;
    15 int n,q,cnt;
    16 int rt[N],ls[N*22],rs[N*22],sum[N*22];
    17 void up(int &o,int pre,int l,int r,int p){
    18     o=++cnt;
    19     sum[o]=sum[pre]+1;
    20     ls[o]=ls[pre];
    21     rs[o]=rs[pre];
    22     if(l==r)return;
    23     int m=(l+r)/2;
    24     if(p<=m)up(ls[o],ls[pre],l,m,p);
    25     else up(rs[o],rs[pre],m+1,r,p);
    26 }
    27 int qu(int o,int pre,int l,int r,int ql,int qr){
    28     if(l>=ql&&r<=qr){
    29         return sum[o]-sum[pre];
    30     }
    31     int res=0;
    32     int m=(l+r)/2;
    33     if(ql<=m)res+=qu(ls[o],ls[pre],l,m,ql,qr);
    34     if(qr>m)res+=qu(rs[o],rs[pre],m+1,r,ql,qr);
    35     return res;
    36 }
    37 int check(int p,int x,int ql,int qr,int h,int k){
    38     int res=qu(rt[qr],rt[ql-1],1,h,max(1,p-x),min(p+x,h));
    39     if(res>=k)return 1;
    40     return 0;
    41 }
    42 int main(){
    43     int T;
    44     scanf("%d",&T);
    45     int h=1e6;
    46     while(T--){
    47         scanf("%d%d",&n,&q);
    48         for(int i=1;i<=n;i++){
    49             int x;
    50             scanf("%d",&x);
    51             up(rt[i],rt[i-1],1,h,x);
    52         }
    53         cnt=0;
    54         int ans=0;
    55         while(q--){
    56             int ql,qr,p,k;
    57             scanf("%d%d%d%d",&ql,&qr,&p,&k);
    58             ql^=ans,qr^=ans,p^=ans,k^=ans;
    59             int l=0,r=1e6;
    60             while(l<r){
    61                 int m=(l+r)/2;
    62                 if(check(p,m,ql,qr,h,k)){
    63                     r=m;
    64                 }
    65                 else l=m+1;
    66             }
    67             printf("%d
    ",ans=r);
    68         }
    69     }
    70 }

     队友代码,给入门主席树用。

     1 #define bug(x) cout<<#x<<" is "<<x<<endl
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 const int maxn = 1e5 + 10, N = 1e6;
     5 int rt[maxn], ls[maxn * 22], rs[maxn * 22], sum[maxn * 22], cnt;
     6 #define m (l + r) / 2
     7 void up(int &o, int pre, int l, int r, int k) {
     8     o = ++cnt;
     9     sum[o] = sum[pre] + 1;
    10     ls[o] = ls[pre];
    11     rs[o] = rs[pre];
    12     if (l == r){
    13         return;
    14     }
    15     if (k <= m)
    16         up(ls[o], ls[pre], l, m, k);
    17     else
    18         up(rs[o], rs[pre], m + 1, r, k);
    19 }
    20 int qu(int o, int pre, int l, int r, int ql, int qr) {
    21     printf("l= %d  r= %d
    ",l,r);
    22     printf("sum[%d]= %d  sum[%d]= %d
    ",o,sum[o],pre,sum[pre]);
    23     puts("");
    24     if (l >= ql && r <= qr)
    25         return sum[o] - sum[pre];
    26     int res = 0;
    27     if (ql <= m)
    28         res += qu(ls[o], ls[pre], l, m, ql, qr);
    29     if (qr > m)
    30         res += qu(rs[o], rs[pre], m + 1, r, ql, qr);
    31     return res;
    32 }
    33 int gao(int x, int len, int l, int r) {
    34     int L = max(x - len, 1);
    35     int R = min(x + len, N);
    36     return qu(rt[r], rt[l - 1], 1, N, L, R);
    37 }
    38 int main() {
    39     int n, q, x, l, r, p, k, ans = 0;
    40     cnt = 0;
    41     for (int i = 1; i <= 3; i++) {
    42         x=i;
    43         up(rt[i], rt[i - 1], 1, 5, x);
    44         printf("rt[%d]= %d
    ",i,rt[i]);
    45         for(int i=0;i<=cnt;i++){
    46             printf("ls[%d]= %d  rs[%d]= %d  sum[%d]= %d
    ",i,ls[i],i,rs[i],i,sum[i]);
    47         }
    48         printf("
    ");
    49     }
    50     int ql=2,qr=3;
    51     int res=qu(rt[qr],rt[ql-1],1,5,1,3);
    52     bug(res);
    53 }
  • 相关阅读:
    字符串匹配算法之SimHash算法
    Shell 判断
    剑指offer 面试题6:重建二叉树
    字符串匹配算法之BF(Brute-Force)算法
    Python变量/运算符/函数/模块/string
    trie树
    AWK文本处理工具(Linux)
    Linux 进程间通信(一)
    Nginx学习笔记(八) Nginx进程启动分析
    进程状态转换、CPU调度算法
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/11298563.html
Copyright © 2011-2022 走看看