区间内x的出现个数(主席树)
Posted lovedsr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间内x的出现个数(主席树)相关的知识,希望对你有一定的参考价值。
题目大概:求区间内x出现的次数
出题人yjy
Description
ZJK 给你一个长度为 n 的数列和 m 次询问,每次询问从第 l 个到第 r 个数中,数 x 出现
了多少次。
Input
第一行一个整数 n,
第二行 n 个整数,表示这个数列。
第三行一个整数 m,表示询问数。
下面 m 行,每行三个整数 l, r, x,表示询问[l, r]之间数 x 出现的次数
Output
对于每个询问操作,输出该询问的答案。答案之间用换行隔开,一共 m 行。
Example
6
1 1 2 3 3 1
8
1 6 1
3 5 3
3 5 2
2 6 1
1 3 3
2 6 3
2 6 4
1 6 2
3
2
1
2
0
2
0
1
Hint
涉及到的数列中所有数 x∈[1, 200000]
序列长度 n <= 100000
询问数 m <= 100000
注意:询问中有可能会询问不存在的数,但一定满足 x ∈ [1, 200000]
主席树板子嘛,比 第k大值 得板子还板子,至于主席树,有空再补一篇吧
add维护数出现的个数,n的范围20w,不用离散化
查询的时候,就一直查询,直到查询到叶节点,然后两点做差
ps:n不是树的大小范围,挂在这里(;′⌒`)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=200010; 7 int n,m,root[MAXN],cut,a[MAXN],s[MAXN]; 8 struct data 9 { 10 int lc,rc,ans; 11 }tree[MAXN*20]; 12 void add(int &now,int last,int l,int r,int x) 13 { 14 now=++cut; 15 tree[now].ans=tree[last].ans+1; 16 17 if(l==r) return ; 18 tree[now].lc=tree[last].lc; 19 tree[now].rc=tree[last].rc; 20 int mid=(l+r)>>1; 21 if(x<=mid) add(tree[now].lc,tree[last].lc,l,mid,x); 22 else add(tree[now].rc,tree[last].rc,mid+1,r,x); 23 } 24 int query(int L,int R,int l,int r,int x) 25 { 26 if(l==r)return tree[L].ans-tree[R].ans; 27 int mid=(l+r)>>1; 28 if(x<=mid)return query(tree[L].lc,tree[R].lc,l,mid,x); 29 else return query(tree[L].rc,tree[R].rc,mid+1,r,x); 30 } 31 int main() 32 { 33 int x,y,z,p=0; 34 scanf("%d",&n); 35 for(int i=1;i<=n;++i) 36 { 37 scanf("%d",&a[i]); 38 p=max(p,a[i]); 39 } 40 for(int i=1;i<=n;++i) 41 add(root[i],root[i-1],1,p,a[i]); 42 scanf("%d",&m); 43 while(m--) 44 { 45 scanf("%d%d%d",&x,&y,&z); 46 if(z>p) { 47 printf("0 "); 48 continue; 49 } 50 printf("%d ",query(root[y],root[x-1],1,p,z)); 51 } 52 return 0; 53 }
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
67 130 266 29 378 430 64 262 527 296 230 340 316 248 210 194 542 276 551 8 581 6 618 607 171 219 332 51 211 82 372 542 219 619 618 261 340 291 329 187 260 419 281 220 155 582 519 590 459 324 211 221 331 438 236 604 524 372 344 368 139 77 446 300 324 140 152 261 51 21 37 148921 30 46 184 17 35 82 17 38 94 41 43 430 51 52 78 16 44 345 55 56 167 52 56 77 27 37 181 2 7 617 25 26 43 65 67 520 54 58 446 4 26 343 32 54 122 2 50 229 29 35 556 9 16 622 25 31 91 34 67 482 1 53 565 29 55 410 49 64 585 25 36 55 21 23 332 29 33 149 22 38 11 6 19 596 39 46 3 42 49 415 6 45 130 19 60 500 2 19 8 54 57 140 51 59 378 33 60 425 1 1 360 2 15 349 5 26 52 4 57 465 25 57 488 2 37 278 17 47 62 54 65 42 13 50 45 22 23 52230 14 35 265 10 33 58083 1 39 74 11 57 128
83 572 371 53 650 67 742 191 44 472 350 234 276 168 507 356 389 105 491 225 380 63 282 209 303 230 125 162 419 451 154 676 83 152 610 614 489 104 617 154 175 195 438 480 722 747 716 161 224 668 178 667 169 739 107 470 748 121 316 423 54 342 261 681 17 545 639 74 113 75 609 459 369 93 225 51 197 556 255 53 706 144 625 757 36 16 79 639 2 33 54 9 82 104 12 45 666 61 63 324 1 49 105421 10 67 508 32 69 310 65 80 417 10 47 720 10 68 665 25 55 322 39 65 412 11 60 9 21 24 243 32 46 380 39 73 555 33 73 494 18 25 518 2 3 727 37 54 676 14 47 147503 57 71 379 24 39 45077 24 72 566 1 10 128 5 34 202 35 82 69 15 40 192 34 74 94 25 63 3 67 69 160166 51 81 281 21 23 631 38 66 289 13 43 588
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
以上是关于区间内x的出现个数(主席树)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)
CF1000F One Occurrence 主席树 线段树