【BZOJ2223&&3524】PATULJCI [主席树]

PATULJCI

Time Limit: 10 Sec  Memory Limit: 259 MB
[Submit][Status][Discuss]

Description

Input

  第一行两个整数n,INF,表示序列长度和ai的上限;
  第二行有n个数,表示ai;
  然后有一个整数m,表示询问个数;
  接下来每行两个l,r,表示询问区间[l,r]中的答案。

Output

  输出m行,表示对于每个询问的答案。如果有这个数,则输出“yes”,然后输出数的值;否则输出“no”。

Sample Input

  10 3
  1 2 1 2 1 2 3 2 3 3
  8
  1 2
  1 3
  1 4
  1 5
  2 5
  2 6
  6 9
  7 10

Sample Output

  no
  yes 1
  no
  yes 1
  no
  yes 2
  no
  yes 3

HINT

  1<=n<=300000 , 1<=m<=10000 , 1<=ai<=10000。

Solution

  显然是一个主席树,我们建立一棵主席树然后查询是否存在个数>(l+r-1)/2的即可。

Code

 1 #include<iostream>    
 2 #include<string>    
 3 #include<algorithm>    
 4 #include<cstdio>    
 5 #include<cstring>    
 6 #include<cstdlib>    
 7 #include<cmath>
 8 using namespace std;  
 9    
10 const int ONE=300005;
11  
12 int n,INF,m;
13 int x,y,cnt;
14 int res_value,res_num;
15  
16 struct power
17 {
18         int root;
19         int value;
20         int left,right;
21 }Node[ONE*19];
22    
23 int get()
24 {    
25         int res=1,Q=1;char c;    
26         while( (c=getchar())<48 || c>57 ) 
27         if(c=='-')Q=-1; 
28         res=c-48;     
29         while( (c=getchar())>=48 && c<=57 )    
30         res=res*10+c-48;    
31         return res*Q;    
32 }
33  
34 void Update(int &x,int y,int L,int R,int Q)
35 {
36         x = ++cnt;
37         Node[x].left = Node[y].left;
38         Node[x].right = Node[y].right;
39         Node[x].value = Node[y].value + 1;
40         if(L == R) return;
41          
42         int M = (L+R)>>1;
43         if(Q <= M)
44             Update(Node[x].left,Node[y].left, L,M, Q);
45         else
46             Update(Node[x].right,Node[y].right, M+1,R, Q);
47 }
48  
49 void Query(int x,int y,int L,int R,int Kth)
50 {
51         if(L == R)
52         {
53             res_value = L;
54             res_num = Node[y].value - Node[x].value;
55             return;
56         }
57          
58         int M = (L+R)>>1;
59         int record = Node[Node[y].left].value - Node[Node[x].left].value;
60          
61         if(Kth < record)
62             Query(Node[x].left,Node[y].left, L,M, Kth);
63         else
64             Query(Node[x].right,Node[y].right, M+1,R, Kth);
65 }
66   
67 int main() 
68 {
69         n=get();    INF=get();
70         for(int i=1;i<=n;i++)
71         {
72             x=get();
73             Update(Node[i].root,Node[i-1].root, 1,INF, x);
74         }
75          
76         m=get();
77         for(int i=1;i<=m;i++)
78         {
79             x=get();    y=get();
80              
81             res_value = 0, res_num = 0;
82             int M = (y-x+1)/2;
83             Query(Node[x-1].root,Node[y].root, 1,INF, M);
84              
85             if(res_num > M)
86                 printf("yes %d",res_value);
87             else
88                 printf("no");
89             printf("\n");
90         }
91 }
View Code



posted @ 2017-02-28 21:25  BearChild  阅读(175)  评论(0编辑  收藏  举报