多校10 1007 CRB and Queries

CRB and Queries

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 3233    Accepted Submission(s): 148

Problem Description

There are N boys in CodeLand.
Boy i has his coding skill Ai.
CRB wants to know who has the suitable coding skill.
So you should treat the following two types of queries.
Query 1: 1 l v
The coding skill of Boy l has changed to v.
Query 2: 2 l r k
This is a report query which asks the k-th smallest value of coding skill between Boy l and Boy r(both inclusive).

Input

There are multiple test cases. 
The first line contains a single integer N.
Next line contains N space separated integers A1, A2, …, AN, where Ai denotes initial coding skill of Boy i.
Next line contains a single integer Q representing the number of queries.
Next Q lines contain queries which can be any of the two types.
1 ≤ N, Q ≤ 105
1 ≤ Ai, v ≤ 109
1 ≤ l ≤ r ≤ N
1 ≤ k ≤ r – l + 1

Output

For each query of type 2, output a single integer corresponding to the answer in a single line.

Sample Input

5
1 2 3 4 5
3
2 2 4 2
1 3 6
2 2 4 2

Sample Output

3
4

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <cstring>
  6
  7 using namespace std;
  8
  9 struct treap_node
 10 {
 11     treap_node *left,*right;
 12     int v,fix,size,weight;
 13     inline int lsize() {return left ?left ->size:0;}
 14     inline int rsize() {return right?right->size:0;}
 15 };
 16
 17 struct sgt_node
 18 {
 19     sgt_node *left,*right;
 20     int a,b;
 21     treap_node *treap;
 22 };
 23
 24 const int MAXN=100000,MAXM=100000,INF=0x7FFFFFFF/2;
 25 const int MAXTN=(MAXN+MAXM)*16,MAXSN=MAXN*2;
 26 treap_node TS[MAXTN];
 27 sgt_node SS[MAXSN];
 28 int D,N,M,TC,SC,Tcnt;
 29 sgt_node *sgt_root;
 30 treap_node *T[MAXN];
 31
 32 inline treap_node* new_treap_node(int v)
 33 {
 34     TS[++TC].v=v;
 35     TS[TC].left=TS[TC].right=0;
 36     TS[TC].size=TS[TC].weight=1;
 37     TS[TC].fix=rand();
 38     return &TS[TC];
 39 }
 40
 41 inline void treap_rotate_right(treap_node *&p)
 42 {
 43     treap_node *q=p->left;
 44     p->left=q->right;
 45     q->right=p;
 46     p=q;
 47     q=p->right;
 48     q->size=q->lsize() + q->rsize() +q->weight;
 49     p->size=p->lsize() + p->rsize() +p->weight;
 50 }
 51
 52 inline void treap_rotate_left(treap_node *&p)
 53 {
 54     treap_node *q=p->right;
 55     p->right=q->left;
 56     q->left=p;
 57     p=q;
 58     q=p->left;
 59     q->size=q->lsize() + q->rsize() +q->weight;
 60     p->size=p->lsize() + p->rsize() +p->weight;
 61 }
 62
 63 int treap_find(treap_node *p,int v)
 64 {
 65     if (!p)
 66         return 0;
 67     else if (v<p->v)
 68         return treap_find(p->left,v);
 69     else if (v>p->v)
 70         return treap_find(p->right,v);
 71     else
 72         return p->weight;
 73 }
 74
 75 void treap_insert(treap_node *&p,int v)
 76 {
 77     if (!p)
 78         p=new_treap_node(v);
 79     else
 80     {
 81         p->size++;
 82         if (v < p->v)
 83         {
 84             treap_insert(p->left,v);
 85             if (p->left->fix < p->fix)
 86                 treap_rotate_right(p);
 87         }
 88         else if (v > p->v)
 89         {
 90             treap_insert(p->right,v);
 91             if (p->right->fix < p->fix)
 92                 treap_rotate_left(p);
 93         }
 94         else
 95             p->weight++;
 96     }
 97 }
 98
 99 void treap_delete(treap_node *&p) //real deletion
100 {
101     if (p->left && p->right)
102     {
103         if (p->left->fix < p->right->fix)
104         {
105             treap_rotate_right(p);
106             treap_delete(p->right);
107         }
108         else
109         {
110             treap_rotate_left(p);
111             treap_delete(p->left);
112         }
113     }
114     else
115     {
116         if (p->left)
117             p=p->left;
118         else
119             p=p->right;
120     }
121 }
122
123 void treap_delete(treap_node *&p,int v) //lazy deletion
124 {
125     if (v==p->v)
126     {
127         p->weight--;
128         p->size--;
129         if (p->weight==0)
130             treap_delete(p);
131     }
132     else
133     {
134         if (v < p->v)
135             treap_delete(p->left,v);
136         else
137             treap_delete(p->right,v);
138         p->size--;
139     }
140 }
141
142 void treap_succ(treap_node *p,int v,int &rs)
143 {
144     if (!p) return;
145     if (p->v >= v)
146     {
147         rs=p->v;
148         treap_succ(p->left,v,rs);
149     }
150     else
151         treap_succ(p->right,v,rs);
152 }
153
154 int treap_getmin(treap_node *p)
155 {
156     while (p->left)
157         p=p->left;
158     return p->v;
159 }
160
161 int treap_getmax(treap_node *p)
162 {
163     while (p->right)
164         p=p->right;
165     return p->v;
166 }
167
168 void treap_rank(treap_node *p,int v,int cur,int &rank)
169 {
170     if (v == p->v)
171         rank=p->lsize() + cur + 1;
172     else if (v < p->v)
173         treap_rank(p->left,v,cur,rank);
174     else
175         treap_rank(p->right,v,p->lsize() + cur + p->weight,rank);
176 }
177
178 inline sgt_node* new_sgt_node()
179 {
180     SS[++SC].treap=0;
181     SS[SC].a=SS[SC].b=0;
182     SS[SC].left=SS[SC].right=0;
183     return &SS[SC];
184 }
185
186 void sgt_build(sgt_node *&p,int a,int b)
187 {
188     p=new_sgt_node();
189     if (a==b)
190         p->a=p->b=a;
191     else
192     {
193         int m=(a+b) >> 1;
194         sgt_build(p->left,a,m);
195         sgt_build(p->right,m+1,b);
196         p->a=a;p->b=b;
197     }
198 }
199
200 int sgt_edit(sgt_node *p,int k,int v,bool del)
201 {
202     int delter=0;
203     if (p->a==p->b)
204     {
205         if (del)
206             delter=p->treap->v;
207     }
208     else
209     {
210         int m=(p->a+p->b) >> 1;
211         if (k>=p->a && k<=m)
212             delter=sgt_edit(p->left,k,v,del);
213         else
214             delter=sgt_edit(p->right,k,v,del);
215     }
216     if (del)
217         treap_delete(p->treap,delter);
218     treap_insert(p->treap,v);
219     return delter;
220 }
221
222 void sgt_get(sgt_node *p,int a,int b)
223 {
224     if (p->a==a && p->b==b)
225         T[++Tcnt]=p->treap;
226     else
227     {
228         int m=(p->a+p->b) >> 1;
229         if (b<=m)
230             sgt_get(p->left,a,b);
231         else if (a>=m+1)
232             sgt_get(p->right,a,b);
233         else
234         {
235             sgt_get(p->left,a,m);
236             sgt_get(p->right,m+1,b);
237         }
238     }
239 }
240
241
242 int check(int result,int k)
243 {
244     int totalrankL,totalrankR,minsucc=INF;
245     int i,rank,succ,totalrank=0,totalcount=0;
246     for (i=1;i<=Tcnt;i++)
247     {
248         succ=INF;
249         treap_succ(T[i],result,succ);
250         if (succ==INF)
251             rank=T[i]->size+1;
252         else
253             treap_rank(T[i],succ,0,rank);
254         totalrank+=rank-1;
255         if (succ < minsucc)
256             minsucc=succ;
257     }
258     for (i=1;i<=Tcnt;i++)
259         totalcount+=treap_find(T[i],minsucc);
260     totalrankL=++totalrank;
261     totalrankR=totalrank+totalcount-1;
262     if (k>=totalrankL && k<=totalrankR)
263     {
264         printf("%d\n",minsucc);
265         return 0;
266     }
267     else if (totalrankL > k)
268         return 1;
269     else
270         return -1;
271 }
272
273 void binary(int a,int b,int k)
274 {
275     int Min=INF,Max=0,i,m,r;
276     Tcnt=0;
277     sgt_get(sgt_root,a,b);
278     for (i=1;i<=Tcnt;i++)
279     {
280         m=treap_getmax(T[i]);
281         if (m>Max)
282             Max=m;
283         m=treap_getmin(T[i]);
284         if (m<Min)
285             Min=m;
286     }
287     m=(Max+Min)>>1;
288     do
289     {
290         r=check(m,k); //-1=smaller 1=bigger
291         if (r<0)
292         {
293             Min=m;
294             m=(m+Max+1)>>1;
295         }
296         else if (r>0)
297         {
298             Max=m;
299             m=(Min+m)>>1;
300         }
301     }while (r!=0);
302 }
303
304 void request()
305 {
306     scanf ("%d", &M);
307     int i,a,b,c,j=0;
308     int op;
309     for (i=1;i<=M;i++)
310     {
311         scanf ("%d", &op);
312         if (op == 1)
313         {
314             scanf("%d%d",&a,&b);
315             sgt_edit(sgt_root,a,b,true);
316         }
317         else
318         {
319             scanf("%d%d%d",&a,&b,&c);
320             binary(a,b,c);
321         }
322     }
323 }
324
325 int main()
326 {
327     while (scanf ("%d", &N) == 1)   {
328         int i,v;
329         TC=SC=-1;
330         sgt_root=0;
331         sgt_build(sgt_root,1,N);
332         for (i=1;i<=N;i++)
333         {
334             scanf("%d",&v);
335             sgt_edit(sgt_root,i,v,false); //non-deletion
336         }
337         request();
338     }
339
340     return 0;
341 }

时间: 2024-10-08 15:37:38

多校10 1007 CRB and Queries的相关文章

hdu5414(2015多校10)--CRB and String(字符串匹配)

题目链接:pid=5414">点击打开链接 题目大意:有A.B两个字符串.如今有一种操作能够在A的随意一个字符x后面添加一个字符y(x.=y).问能不能将A变为B. 首先假设A能够变成B,那么A就一定是B的一个子序列,这个能够在O(n+m)的时间内算出. 假设A是B的子序列之后,推断添加的字符中是不是含有不能添加的情况,我们仅仅须要推断B从開始的一段连续的同样的字符串.是不是在A的开头也存在.假设存在,那么就是能够由A转化成B的. #include <cstdio> #incl

hdu5410(2015多校10)--CRB and His Birthday(背包问题)

题目链接:点击打开链接 题目大意:有m块钱,有n种货物,每种货物都有一个wi的价钱,假设买了x个i中货物,会花wi*x的钱,同时老板还会赠送a*x+b的糖果,问怎么样买礼物,可以让糖果数最多. dp[i][j][0]当买到第i种的时候,花钱是j且没有买过i能得到最多的糖果数. dp[i][j][1]当买到第i种的时候,花钱是j且买过i能得到的最多的糖果数. 按照货物数遍历从1到n,那么就可以省略一维,dp[i][0]在当前物品时,花钱为j的不买当前这件物品的最大值,dp[i][1]在当前物品时,

HDU 5412——CRB and Queries——————【线段树套Treap(并没有AC)】

CRB and Queries Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1602    Accepted Submission(s): 409 Problem Description There are N boys in CodeLand.Boy i has his coding skill Ai.CRB wants to

hdu 5412 CRB and Queries

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5412 CRB and Queries Description There are $N$ boys in CodeLand. Boy i has his coding skill $A_{i}$. CRB wants to know who has the suitable coding skill. So you should treat the following two types of qu

2015 多校 #5 1007 MZL&#39;s simple problem

MZL's simple problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2541    Accepted Submission(s): 694 Problem Description A simple problemProblem DescriptionYou have a multiple set,and now th

hdu 5412 CRB and Queries(线段树套笛卡尔树 - 动态区间第k大)

题目链接:hdu 5412 CRB and Queries 首先对所有出现过的值排序,建立线段树,每个线段树的节点是一棵笛卡尔树,笛卡尔树记录区间下标值. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define lson(x) (x<<1) #define rson(x) ((x<<

hdu 4972 A simple dynamic programming problem (转化 乱搞 思维题) 2014多校10

题目链接 题意:给定一个数组记录两队之间分差,只记分差,不记谁高谁低,问最终有多少种比分的可能性 分析: 类似cf的题目,比赛的时候都没想出来,简直笨到极点..... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <vector> 7 #include &

HDU 4975 (杭电多校 #10 1005题)A simple Gaussian elimination problem.(网络流之最大流)

题目地址:HDU 4975 对这题简直无语...本来以为这题要用什么更先进的方法,结果还是老方法,这么卡时间真的好吗....比赛的时候用了判环的方法,一直TLE..后来换了矩阵DP的方式,加了加剪枝就过了..无语了.. 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cstdio> #include <

HDU 5863 cjj&#39;s string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但是 m 很小的时候 发现此题DP并不合适.于是想可能是某种组合数学的问题可以直接公式算 看到题解的我.恍然大悟.对于这种数据.可以考虑一下矩阵快速幂优化的DP 首先要想到线性递推的 DP 式子 最直观的想法就是 dp[i][j] = 到第 i 个位置为止.前面最长匹配长度为 j 的方案数 但是如果仔