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\n",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:\n",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\n",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\n",sort_b[ans]);
81        }
82     }
83     return 0;
84 }