• 主席树模板之区间问题


     

     AC_Code

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef long long ll;
     8 #define rep(i,first,last) for(int i=first;i<=last;i++)
     9 #define dep(i,first,last) for(int i=first;i>=last;i--)
    10 const int maxn=1e5+6;
    11 int n,m,cnt,root[maxn],a[maxn],x,y,k;//root为根节点编号
    12 struct node{int l,r,sum;}T[maxn*50];//l:左儿子编号,r:右儿子编号,sum:值域元素个数和,开40~60倍
    13 vector<int>v;
    14 int getid(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
    15 void updata(int l,int r,int &x,int y,int pos){
    16     T[++cnt]=T[y],T[cnt].sum++,x=cnt;
    17     if(l==r) return ;
    18     int mid=(l+r)>>1;
    19     if( pos>mid ) updata(mid+1,r,T[x].r,T[y].r,pos);
    20     else updata(l,mid,T[x].l,T[y].l,pos);
    21 }
    22 int query(int l,int r,int x,int y,int k){//传的x,y为编号
    23     if( l==r )return l;
    24     int mid=(l+r)>>1;
    25     int sum=T[T[y].l].sum-T[T[x].l].sum;
    26     if( sum>=k ) return query(l,mid,T[x].l,T[y].l,k);
    27     else return query(mid+1,r,T[x].r,T[y].r,k-sum);
    28 }
    29 
    30 int main()
    31 {
    32     scanf("%d%d",&n,&m);
    33     rep(i,1,n) scanf("%d",&a[i]),v.push_back(a[i]);
    34     sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
    35     rep(i,1,n) updata(1,n,root[i],root[i-1],getid(a[i]));
    36     rep(i,1,m){
    37         scanf("%d%d%d",&x,&y,&k);
    38         printf("%d
    ",v[query(1,n,root[x-1],root[y],k)-1]);
    39     }
    40     return 0;
    41 }

     例题二:P3567 [POI2014]KUR-Couriers

    AC_Code;

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=5e5+10;
     5 const int mod=1e9+9;
     6 
     7 struct node{
     8     int l,r,v;
     9 }tree[maxn*40];
    10 int a[maxn],root[maxn],n,q,m,tot;
    11 vector<int>v;
    12 int getid(int x){
    13     return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
    14 }
    15 
    16 
    17 int build(int l,int r){
    18     int p=++tot;
    19     if( l<r ){
    20         int mid=(l+r)>>1;
    21         tree[p].l=build(l,mid);
    22         tree[p].r=build(mid+1,r);
    23     }
    24     return p;
    25 }
    26 
    27 int update(int pre, int l,int r,int x){
    28     int p=++tot;
    29     tree[p].l=tree[pre].l;
    30     tree[p].r=tree[pre].r;
    31     tree[p].v=tree[pre].v+1;
    32     if( l<r ){
    33         int mid=(l+r)>>1;
    34         if( x<=mid ) tree[p].l=update(tree[pre].l,l,mid,x);
    35         else tree[p].r=update(tree[pre].r,mid+1,r,x);
    36     }
    37     return p;
    38 }
    39 
    40 int query(int pre,int now,int l,int r,int len){
    41     if( l>=r ) return l;
    42     int l1=tree[tree[now].l].v-tree[tree[pre].l].v;//计算当前区间大于等于l小于等于mid的数字的数量
    43     int rl=tree[tree[now].r].v-tree[tree[pre].r].v;//大于mid小于等于r的数字的数量
    44     int mid=(l+r)>>1;
    45     if( l1>len ) return query(tree[pre].l,tree[now].l,l,mid,len);//如果大于等于l小于等于mid的数字的数量超过一半就往下查询
    46     if( rl>len ) return query(tree[pre].r,tree[now].r,mid+1,r,len);//如果大于mid小于等于r的数字的数量超过一半就往下查询
    47     return 0;
    48 }
    49 
    50 int main()
    51 {
    52     scanf("%d%d",&n,&q);
    53     for(int i=1;i<=n;i++){
    54         scanf("%d",&a[i]);
    55         v.push_back(a[i]);
    56     }
    57     sort(v.begin(),v.end());
    58     v.erase(unique(v.begin(),v.end()),v.end());
    59     m=v.size();
    60     root[0]=build(1,m);
    61     for(int i=1;i<=n;i++){
    62         int id=getid(a[i]);
    63         root[i]=update(root[i-1],1,m,id);
    64     }
    65     while( q-- ){
    66         int a1,a2;
    67         scanf("%d%d",&a1,&a2);
    68         int f=query(root[a1-1],root[a2],1,m,(a2-a1+1)/2);
    69         if( f==0 ) printf("0
    ");
    70         else printf("%d
    ", v[f-1]);
    71     }
    72     return 0;
    73 }

     

  • 相关阅读:
    关于Netty4.x中文教程系列更新进度的说明和道歉
    Netty4.x中文教程系列(四) ChannelHandler
    Netty4.x中文教程系列(三) Hello World !详解
    Netty4.x中文教程系列(二) Hello World !
    Netty4.x中文教程系列(一) 目录及概述
    【推荐】HTML5 UI框架 推荐
    【转载】【JQuery学习】jQuery插件开发
    前端与后端的数据交互(jquery ajax+python flask)
    【JS教程32】ajax
    【JS教程31】json
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12343587.html
Copyright © 2020-2023  润新知