• 线段树专题2-(加强版线段树-可持续化线段树)主席树 orz! ------用于解决区间第k大的问题----xdoj-1216


    poj-2104(区间第K大问题)

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstring>
     5 using namespace std;
     6 struct T {
     7     int ls;
     8     int rs;
     9     int sum;
    10 };
    11 const int N=1e5+7;
    12 T tri[40*N];
    13 int a[N],sort_a[N];
    14 int rt[N];
    15 int cnt;
    16 int n,m;
    17 void update (int l,int r,int rt1,int &rt2,int pos) {
    18     rt2=++cnt;
    19     tri[rt2]=tri[rt1];
    20     tri[rt2].sum++;// 在此处直接更新,就不用pushup了
    21     if (l==r) return ;
    22     int mid=(l+r)/2;
    23     if (pos<=mid) update (l,mid,tri[rt1].ls,tri[rt2].ls,pos);
    24     else          update (mid+1,r,tri[rt1].rs,tri[rt2].rs,pos);
    25     return ;
    26 }
    27 int  query (int l,int r,int rt1,int rt2,int k) {
    28     if (l==r)  return sort_a[l];
    29     int mid=(l+r)/2;
    30     int sum=tri[tri[rt2].ls].sum-tri[tri[rt1].ls].sum;//我又出错了 sum应该是左子树的节点数 T_T !
    31     if (k<=sum)   return query (l,mid,tri[rt1].ls,tri[rt2].ls,k);
    32     else          return  query (mid+1,r,tri[rt1].rs,tri[rt2].rs,k-sum); 
    33 }
    34 int main ()
    35 {
    36     scanf ("%d %d",&n,&m);
    37     for (int i=1;i<=n;i++) {
    38         scanf ("%d",&a[i]);
    39         sort_a[i]=a[i];
    40     }
    41     sort (sort_a+1,sort_a+1+n);
    42     int num=1;
    43     for (int i=2;i<=n;i++) {
    44         if (sort_a[i]!=sort_a[i-1])
    45             sort_a[++num]=sort_a[i];//离散化
    46     }
    47     rt[0]=cnt=0;
    48     tri[0].sum=tri[0].ls=tri[0].rs=0;
    49     for (int i=1;i<=n;i++) {
    50         int pos=lower_bound (sort_a+1,sort_a+1+num,a[i])-sort_a;
    51         update (1,num,rt[i-1],rt[i],pos);
    52     }
    53     for (int i=1;i<=m;i++) {
    54         int x,y,k;
    55         scanf ("%d %d %d",&x,&y,&k);
    56         printf("%d
    ",query (1,num,rt[x-1],rt[y],k));
    57     }
    58     return 0;
    59 }

    NO.2   HDOJ-4417(主席数的区间求和)

     1 #include<cstdio>
     2 #include<algorithm>
     3 const int N=1e5+7;
     4 using namespace std;
     5 struct node {
     6     int ls;
     7     int rs;
     8     int sum;
     9 };
    10 node tri[40*N];
    11 int rt[N];
    12 int a[N],sort_a[N+1];
    13 int cnt,n,m,x,y,k;
    14 void updata (int l,int r,int rt1,int& rt2,int pos) {
    15     rt2=(++cnt);
    16     tri[rt2]=tri[rt1];
    17     tri[rt2].sum++;
    18     if (l==r) return ;
    19     int mid=(l+r)/2;
    20     if (pos<=mid) updata(l,mid,tri[rt1].ls,tri[rt2].ls,pos);
    21     else          updata(mid+1,r,tri[rt1].rs,tri[rt2].rs,pos);
    22     return ;
    23 }
    24 int query (int l,int r,int L,int R,int rt1,int rt2) {
    25     if (r<L||l>R) return 0;
    26     if (l>=L&&r<=R) return tri[rt2].sum-tri[rt1].sum;
    27     int mid=(l+r)/2;
    28     int t1=query(l,mid,L,R,tri[rt1].ls,tri[rt2].ls);
    29     int t2=query(mid+1,r,L,R,tri[rt1].rs,tri[rt2].rs);
    30     return t1+t2;
    31 }
    32 int main ()
    33 {
    34     int T;
    35     int tt=1;
    36     scanf ("%d",&T);
    37     while (T--) {
    38         printf("Case %d:
    ",tt++);
    39         scanf ("%d %d",&n,&m);
    40         for (int i=1;i<=n;i++) {
    41             scanf ("%d",&a[i]);
    42             sort_a[i]=a[i];
    43         }
    44         sort(sort_a+1,sort_a+1+n);
    45         int num=1;
    46         for (int i=2;i<=n;i++) {
    47             if (sort_a[i]!=sort_a[num])
    48                 sort_a[++num]=sort_a[i];
    49         }
    50         cnt=0;
    51         rt[0]=0;
    52         tri[0].ls=tri[0].rs=tri[0].sum=0;
    53         for (int i=1;i<=n;i++) {
    54             int pos=lower_bound(sort_a+1,sort_a+1+num,a[i])-sort_a;
    55             updata(1,num,rt[i-1],rt[i],pos);
    56         }
    57         for (int i=1;i<=m;i++) {
    58             scanf ("%d %d %d",&x,&y,&k);
    59             int t=lower_bound(sort_a+1,sort_a+1+num,k)-sort_a;
    60             if (t>num||sort_a[t]>k) t--;// 这个好  找最后一个小于等于k的数
    61             int ans=query (1,num,1,t,rt[x],rt[y+1]);// 因为题目从0开始计数
    62             printf("%d
    ",ans);
    63         }
    64     }
    65     return 0;
    66 }

     No.3 xdoj-1216(子树第k小)——dfs+主席树

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 using namespace std;
     5 const int N=1e5+7;
     6 struct T{
     7     int ls;
     8     int rs;
     9     int sum;
    10 };
    11 vector < vector <int> > g(N);
    12 T tri[N*40];
    13 int rt[N],b[N],sort_b[N];
    14 int in[N],out[N];
    15 int val[N];
    16 int cnt,num;
    17 int n,q;
    18 int x,k;
    19 void dfs (int id,int pre) {
    20     num++;
    21     sort_b[num]=b[num]=val[id];
    22     in[id]=num;
    23     for (int i=0;i<g[id].size();i++) {
    24         int  next=g[id][i];
    25         if (next==pre) continue;
    26         dfs (next,id);
    27     }
    28     out[id]=num;
    29 }
    30 void updata (int l,int r,int pos,int rt1,int& rt2) {
    31     cnt++;
    32     rt2=cnt;
    33     tri[cnt]=tri[rt1];
    34     tri[cnt].sum++;
    35     if (l==r) return ;
    36     int mid=(l+r)/2;
    37     if (pos<=mid) updata (l,mid,pos,tri[rt1].ls,tri[rt2].ls);
    38     else          updata (mid+1,r,pos,tri[rt1].rs,tri[rt2].rs);
    39     return ;
    40 }
    41 int query (int l,int r,int k,int rt1,int rt2) {
    42     if (l==r) return l;
    43     int mid=(l+r)/2;
    44     int ans;
    45     int sum=tri[tri[rt2].ls].sum-tri[tri[rt1].ls].sum;
    46     if (k<=sum) ans=query (l,mid,k,tri[rt1].ls,tri[rt2].ls);
    47     else        ans=query (mid+1,r,k-sum,tri[rt1].rs,tri[rt2].rs);
    48     return ans;
    49 }
    50 int main ()
    51 {
    52     while (scanf ("%d",&n)!=EOF) {
    53         for (int i=1;i<=n;i++) g[i].clear();
    54         for (int i=1;i<=n;i++)
    55             scanf ("%d",&val[i]);
    56         int u,v;
    57         for (int i=1;i<=n-1;i++) {
    58             scanf ("%d %d",&u,&v);
    59             g[u].push_back(v);
    60             g[v].push_back(u);
    61         }
    62         num=0;
    63         dfs (1,-1);// 按理说有根树 直接dfs(1)就可以了可是这样答案是不对的 是我理解错了还是数据有问题呢
    64         sort(sort_b+1,sort_b+1+n);
    65         int nn=1;
    66         for (int i=2;i<=n;i++)
    67             if (sort_b[i]!=sort_b[nn])
    68                 sort_b[++nn]=sort_b[i];
    69        rt[0]=0;
    70        tri[0].rs=tri[0].ls=tri[0].sum=0;
    71        cnt=0;
    72        for (int i=1;i<=n;i++) {
    73             int pos=lower_bound(sort_b+1,sort_b+1+nn,b[i])-sort_b;
    74             updata(1,nn,pos,rt[i-1],rt[i]);
    75        }
    76        scanf ("%d",&q);
    77        for (int i=1;i<=q;i++)  {
    78             scanf ("%d %d",&x,&k);
    79             int ans=query (1,nn,k,rt[in[x]-1],rt[out[x]]);
    80             printf ("%d
    ",sort_b[ans]);
    81        }
    82     }
    83     return 0;
    84 }
    抓住青春的尾巴。。。
  • 相关阅读:
    NLP入门之语音模型原理
    NLP入门之语音模型原理
    NLP入门之语音模型原理
    TCP/IP 协议
    TCP/IP 协议
    TCP/IP 协议
    TCP/IP 协议
    Android -- 官方下拉刷新SwipeRefreshLayout
    Android -- 官方下拉刷新SwipeRefreshLayout
    创业屡战屡败,如何找回激情?
  • 原文地址:https://www.cnblogs.com/xidian-mao/p/8526968.html
Copyright © 2020-2023  润新知