soj116 快乐串

题意:

标程:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int Max=1e7;
 4 const int N=200005;
 5 int rg[N],lf[N],a[N],n,m,l,r,ans,res,bit[N],L,R,b[N];
 6 int lowbit(int x){return x&(-x);}
 7 void add(int x,int y){while (x<=n) bit[x]+=y,x+=lowbit(x);}
 8 int qry(int x){int res=0;while (x) res+=bit[x],x-=lowbit(x);return res;}
 9 int find(int x)//bit二分找rank(x) 
10 {
11     int l=0,r;
12     for (int i=20;i>=0&&x;i--)
13       if ((r=l+(1<<i))<=n&&bit[r]<x) x-=bit[l=r];
14     return l+1;
15 }
16 bool cmp(int x,int y){return a[x]<a[y];}
17 void init(int k)
18 {
19   L=1;R=1;
20   for (int i=1;i<=n;i++)
21   {
22          while (R<=n&&a[b[R]]<=a[b[i]]+k) add(b[R++],1);
23          while (L<=n&&a[b[L]]<a[b[i]]-k) add(b[L++],-1);
24          int t=qry(b[i]),sum=qry(n);
25         lf[b[i]]=t==1?0:find(t-1);rg[b[i]]=t==sum?n+1:find(t+1); 
26   }
27   while (L<=n) add(b[L++],-1);
28 }
29 void solve(int l,int r)
30 {
31   if (r-l+1<m||res>=m) return;
32   int L=l,R=r,pos=0;
33   while (L<=R)
34   {
35     if (lf[L]<l&&rg[L]>r) {pos=L;break;}
36     if (lf[R]<l&&rg[R]>r) {pos=R;break;}
37     L++;R--;
38   }
39   if (!pos) res=max(res,r-l+1);
40   solve(l,pos-1);solve(pos+1,r);
41 }
42 int main()
43 {
44   scanf("%d%d",&n,&m);
45   for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=i;
46   sort(b+1,b+n+1,cmp);
47   l=0;r=1e7;
48   while (l<=r)
49   {
50     int mid=(l+r)>>1;res=0;
51     if (init(mid),solve(1,n),res>=m) ans=mid,r=mid-1;else l=mid+1;
52   }
53   printf("%d\n",ans);
54   return 0;
55 }

猜你喜欢

转载自www.cnblogs.com/Scx117/p/9066855.html
116