HDU3727--Jewel (主席树 静态区间第k大)

Jewel

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 985    Accepted Submission(s): 247


Problem Description
Jimmy wants to make a special necklace for his girlfriend. He bought many beads with various sizes, and no two beads are with the same size. Jimmy can't remember all the details about the beads, for the necklace is so long. So he turns to you for help.

Initially, there is no bead at all, that is, there is an empty chain. Jimmy always sticks the new bead to the right of the chain, to make the chain longer and longer. We number the leftmost bead as Position 1, and the bead to its right as Position 2, and so on. Jimmy usually asks questions about the beads' positions, size ranks and actual sizes. Specifically speaking, there are 4 kinds of operations you should process:

Insert x 
Put a bead with size x to the right of the chain (0 < x < 231, and x is different from all the sizes of beads currently in the chain)
Query_1 s t k 
Query the k-th smallest bead between position s and t, inclusive. You can assume 1 <= s <= t <= L, (L is the length of the current chain), and 1 <= k <= min (100, t-s+1)
Query_2 x
Query the rank of the bead with size x, if we sort all the current beads by ascent order of sizes. The result should between 1 and L (L is the length of the current chain)
Query_3 k
Query the size of the k-th smallest bead currently (1 <= k <= L, L is the length of the current chain)

 
Input
There are several test cases in the input. The first line for each test case is an integer N, indicating the number of operations. Then N lines follow, each line contains one operation, as described above. 

You can assume the amount of "Insert" operation is no more than 100000, and the amounts of "Query_1", "Query_2" and "Query_3" are all less than 35000.
There are several test cases in the input. The first line for each test case is an integer N, indicating the number of operations. Then N lines follow, each line contains one operation, as described above. 

You can assume the amount of "Insert" operation is no more than 100000, and the amounts of "Query_1", "Query_2" and "Query_3" are all less than 35000.Query the rank of the bead with size x, if we sort all the current beads by ascent order of sizes. The result should between 1 and L (L is the length of the current chain)
Query_3 k
Query the size of the k-th smallest bead currently (1 <= k <= L, L is the length of the current chain)

 
Output
Output 4 lines for each test case. The first line is "Case T:", where T is the id of the case. The next 3 lines indicate the sum of results for Query_1, Query_2 and Query_3, respectively. 

 
Sample Input
10
Insert 1
Insert 4
Insert 2
Insert 5
Insert 6
Query_1 1 5 5
Query_1 2 3 2
Query_2 4
Query_3 3
Query_3 1
 
Sample Output
Case 1:
10
3
5
貌似很水的一道题,,主席树裸题,不知道为什么现场就几个队了这个题。。对于查询某个数的排名,我是用树状数组搞的。。和主席树没有联系
注意HDU上的题目有一点问题,,不是231  而是2的31次方
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6 typedef long long ll;
  7 const int maxn = 2e5+100;
  8 int lson[maxn*20],rson[20*maxn],c[maxn*20];
  9 int tree[maxn],tot,idx,maxv;
 10 int build (int l,int r)
 11 {
 12     int root = tot++;
 13     c[root] = 0;
 14     if (l != r)
 15     {
 16         int mid =(l + r) >> 1;
 17         lson[root] = build(l,mid);
 18         rson[root] = build(mid+1,r);
 19     }
 20     return root;
 21 }
 22 int update(int root,int pos,int val)
 23 {
 24     int newroot = tot++;
 25     int tmp = newroot;
 26     int l = 1,r = maxv;
 27     c[newroot] = c[root] + val;
 28     while (l < r)
 29     {
 30         int mid = (l + r) >> 1;
 31         if (pos <= mid)
 32         {
 33             rson[newroot] = rson[root];
 34             root = lson[root];
 35             lson[newroot] = tot++;
 36             newroot = lson[newroot];
 37             r = mid;
 38         }
 39         else
 40         {
 41             lson[newroot] = lson[root];
 42             root = rson[root];
 43             rson[newroot] = tot++;
 44             newroot = rson[newroot];
 45             l = mid + 1;
 46         }
 47         c[newroot] = c[root] + val;
 48     }
 49     return tmp;
 50 }
 51 int query(int left,int right,int k)
 52 {
 53     int l_root = tree[left-1];
 54     int r_root = tree[right];
 55     int l = 1, r = maxv;
 56     while (l < r)
 57     {
 58         int mid = (l + r) >> 1;
 59         if (c[lson[r_root]] - c[lson[l_root]] >= k)
 60         {
 61             r = mid;
 62             l_root = lson[l_root];
 63             r_root = lson[r_root];
 64         }
 65         else
 66         {
 67             l = mid + 1;
 68             k -=  c[lson[r_root]] - c[lson[l_root]];
 69             l_root = rson[l_root];
 70             r_root = rson[r_root];
 71         }
 72     }
 73     return l;
 74 }
 75 int query(int root,int l,int r,int k)
 76 {
 77     if (l == r)
 78         return l;
 79     int mid = (l + r) >> 1;
 80     if (k <= mid)
 81         return query(lson[root],l,mid,k);
 82     else
 83         return c[lson[root]] + query(rson[root],mid+1,r,k);
 84 }
 85 ll bit_arr[maxn];
 86 inline int lowbit (int x)
 87 {
 88     return x & -x;
 89 }
 90 void ADD(int x)
 91 {
 92     while (x < maxn)
 93     {
 94         bit_arr[x]++;
 95         x += lowbit (x);
 96     }
 97 }
 98 ll get_sum(int x)
 99 {
100     ll res = 0;
101     while (x)
102     {
103         res += bit_arr[x];
104         x -= lowbit (x);
105     }
106     return res;
107 }
108 struct
109 {
110     int x,y,k,flag;
111 }Q[maxn];
112 ll vec[maxn];
113 int main(void)
114 {
115     #ifndef ONLINE_JUDGE
116         freopen("in.txt","r",stdin);
117     #endif // ONLINE_JUDGE
118     int n,cas = 1;
119     while (~scanf ("%d",&n))
120     {
121         memset(bit_arr,0,sizeof(bit_arr));
122         printf("Case %d:
",cas++);
123         tot = idx = 0;
124         for (int i = 0; i < n; i++)
125         {
126             char op[15];
127             scanf ("%s",op);
128             if (strcmp(op,"Insert") == 0)
129             {
130                 int x;
131                 scanf ("%d",&x);
132                 Q[i].flag = 0;
133                 Q[i].x = x;
134                 vec[idx++] = x;
135             }
136             if (strcmp(op,"Query_1") == 0)
137             {
138                 int u,v,k;
139                 scanf ("%d%d%d",&u,&v,&k);
140                 Q[i].flag = 1;
141                 Q[i].x = u,Q[i].y = v,Q[i].k = k;
142             }
143             if (strcmp(op,"Query_2") == 0)
144             {
145                 int x;
146                 scanf ("%d",&x);
147                 Q[i].flag = 2;
148                 Q[i].x = x;
149             }
150             if (strcmp(op,"Query_3") == 0)
151             {
152                 int k;
153                 scanf ("%d",&k);
154                 Q[i].flag = 3;
155                 Q[i].x = k;
156             }
157         }
158         sort(vec,vec+idx);
159         idx = unique(vec,vec+idx) - vec;
160         maxv = idx ;
161         tree[0] = build(1,maxv);
162         int now = 1;
163         ll ans1 = 0, ans2 = 0, ans3 = 0;
164         for (int i = 0; i < n; i++)
165         {
166             if (Q[i].flag == 0)
167             {
168                 int tmp = lower_bound(vec,vec+idx,Q[i].x) - vec + 1;
169                 tree[now] = update(tree[now-1],tmp,1);
170                 ADD(tmp);
171                 now++;
172             }
173             if (Q[i].flag == 1)
174             {
175                 ans1 += vec[query(Q[i].x,Q[i].y,Q[i].k)-1];
176             }
177             if (Q[i].flag == 2)
178             {
179                 int tmp = lower_bound(vec,vec+idx,Q[i].x) - vec + 1;
180                 ans2 += get_sum(tmp);
181             }
182             if (Q[i].flag == 3)
183             {
184                 ans3 += vec[query(1,now-1,Q[i].x)-1];
185             }
186         }
187         printf("%I64d
%I64d
%I64d
",ans1,ans2,ans3);
188     }
189     return 0;
190 }
原文地址:https://www.cnblogs.com/oneshot/p/4129284.html