1.(HDOJ6278)http://acm.hdu.edu.cn/showproblem.php?pid=6278

2.(CF961E)http://codeforces.com/problemset/problem/961/E

3.(CF1000F)http://codeforces.com/problemset/problem/1000/F

4.(CF916D)https://www.luogu.org/problemnew/show/CF916D

5.(CQOI2015)https://www.luogu.org/problemnew/show/P3168

6.(POI2014)https://www.luogu.org/problemnew/show/P3567

7.(SCOI2016)https://www.luogu.org/problemnew/show/P3293

8.(SDOI2010)https://www.luogu.org/problemnew/show/P2468

9.(P4137)https://www.luogu.org/problemnew/show/P4137

 

1.(HDOJ6278)http://acm.hdu.edu.cn/showproblem.php?pid=6278

题意:给定一个长度为n的序列,和q个询问,求每个询问[l,r]中最大的h,满足该区间内至少有h个数的值大于h。

分析:主席树+二分答案。每次二分后求区间第mid小的数与mid比较

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 using namespace std;
  6 const int maxn=1e5+10;
  7 const int maxm=5e6+10;
  8 int n,q,m,tot;
  9 int a[maxn],t[maxn];
 10 int T[maxn],lson[maxm],rson[maxm],c[maxm];
 11 
 12 void init_hash()
 13 {
 14     for ( int i=1;i<=n;i++ ) t[i]=a[i];
 15     sort(t+1,t+1+n);
 16     m=unique(t+1,t+1+n)-(t+1);
 17 }
 18 
 19 int build(int l,int r)
 20 {
 21     int root=tot++;
 22     c[root]=0;
 23     if ( l!=r )
 24     {
 25         int mid=(l+r)/2;
 26         lson[root]=build(l,mid);
 27         rson[root]=build(mid+1,r);
 28     }
 29     return root;
 30 }
 31 
 32 int hash_(int x)
 33 {
 34     return lower_bound(t+1,t+1+m,x)-t;
 35 }
 36 
 37 int update(int root,int pos,int val)
 38 {
 39     int rt=tot++,tmp=rt;
 40     c[rt]=c[root]+val;
 41     int l=1,r=m;
 42     while ( l<r )
 43     {
 44         int mid=(l+r)/2;
 45         if ( pos<=mid )
 46         {
 47             lson[rt]=tot++;rson[rt]=rson[root];
 48             rt=lson[rt];root=lson[root];
 49             r=mid;
 50         }
 51         else 
 52         {
 53             rson[rt]=tot++;lson[rt]=lson[root];
 54             rt=rson[rt];root=rson[root];
 55             l=mid+1;
 56         }
 57         c[rt]=c[root]+val;
 58     }
 59     return tmp;
 60 }
 61 
 62 int query(int lrt,int rrt,int k)
 63 {
 64     if ( k==0 ) return 0;
 65     int l=1,r=m;
 66     while ( l<r )
 67     {
 68         int mid=(l+r)/2;
 69         if ( c[lson[rrt]]-c[lson[lrt]]>=k )
 70         {
 71             r=mid;
 72             lrt=lson[lrt];
 73             rrt=lson[rrt];
 74         }
 75         else 
 76         {
 77             l=mid+1;
 78             k-=c[lson[rrt]]-c[lson[lrt]];
 79             lrt=rson[lrt];
 80             rrt=rson[rrt];
 81         }
 82     }
 83     return l;
 84 }
 85 
 86 int main()
 87 {
 88     int Case;
 89     while ( scanf("%d%d",&n,&q)!=EOF )
 90     {
 91         tot=0;
 92         for ( int i=1;i<=n;i++ ) scanf("%d",&a[i]);
 93         init_hash();
 94         T[0]=build(1,m);
 95         for ( int i=1;i<=n;i++ )
 96         {
 97             int pos=hash_(a[i]);
 98             T[i]=update(T[i-1],pos,1);
 99         }
100         while ( q-- )
101         {
102             int l,r,k,mid,L,R,num;
103             scanf("%d%d",&l,&r);
104             L=1,R=r-l+2;
105             while ( R-L>1 )
106             {
107                 mid=(L+R)/2;
108                 k=t[query(T[l-1],T[r],r-l+1-mid+1)];
109                 if ( k>=mid ) L=mid;
110                 else R=mid;
111             }
112             printf("%d\n",L);
113         }
114     }
115     return 0;
116 }
HDOJ6278

相关文章:

  • 2021-08-03
  • 2021-10-02
  • 2022-02-12
  • 2021-10-07
  • 2022-02-23
  • 2022-12-23
  • 2021-06-04
  • 2021-06-08
猜你喜欢
  • 2021-10-28
  • 2021-12-01
  • 2021-04-27
  • 2021-07-01
  • 2021-10-14
  • 2022-12-23
相关资源
相似解决方案