标签:get pre eps team occurred deb out arch define
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 2522 Accepted Submission(s): 1138
Special Judge
求一个序列中的连续子序列S,使得 (S中不同元素的个数)/(S的长度)最小化。挺不错的一道题,很考验思维。对于这种最小化的题目很容易往二分上面想,得到 a/b<=k ,我们只要不断二分k,找到下界即可,问题是对于k如何判定是否可行,枚举所有区间显然不靠谱,考虑这个式子 diff(l,r)/(r-l+1)<=k -> diff(l,r)+k*l<=k*(r+1), 我们可以枚举一下右端点,然后找到一个最优的左端点判断能否使得这个不等式成立即可,可以用线段树区间修改来维护这个值,结点 u(L,R),保存的就是[L,R]中最小的 diff(l,r)+k*l ,显然l€[L,R]。初始化根节点为k*L,然后遍历右端点的时候更新对应的区间,也就是会对那些区间的diff造成变化。
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #include<cstdio> 5 #include<stack> 6 #include<set> 7 #include<map> 8 #include<cmath> 9 #include<ctime> 10 #include<time.h> 11 #include<algorithm> 12 #include<bits/stdc++.h> 13 using namespace std; 14 #define mp make_pair 15 #define pb push_back 16 #define debug puts("debug") 17 #define LL long long 18 #define pii pair<int,int> 19 #define inf 0x3f3f3f3f 20 21 #define mid ((L+R)>>1) 22 #define lc (id<<1) 23 #define rc (id<<1|1) 24 #define eps 1e-5 25 const int _M=60006; 26 double sum[_M<<2]; 27 int laz[_M<<2]; 28 int a[_M],x[_M],pre[_M]; 29 void pushdown(int id){ 30 if(laz[id]){ 31 laz[lc]+=laz[id]; 32 laz[rc]+=laz[id]; 33 sum[lc]+=laz[id]; 34 sum[rc]+=laz[id]; 35 laz[id]=0; 36 } 37 } 38 void pushup(int id){ 39 sum[id]=min(sum[lc],sum[rc]); 40 } 41 void build(int id,int L,int R,double k){ 42 if(L==R){ 43 sum[id]=k*L; 44 return; 45 } 46 build(lc,L,mid,k); 47 build(rc,mid+1,R,k); 48 pushup(id); 49 } 50 void update(int id,int L,int R,int l,int r){ 51 if(L>=l&&R<=r){ 52 sum[id]++; 53 laz[id]++; 54 return ; 55 } 56 pushdown(id); 57 if(l<=mid) update(lc,L,mid,l,r); 58 if(r>mid) update(rc,mid+1,R,l,r); 59 pushup(id); 60 } 61 double query(int id,int L,int R,int l,int r){ 62 if(L>=l&&R<=r){ 63 return sum[id]; 64 } 65 pushdown(id); 66 if(r<=mid) return query(lc,L,mid,l,r); 67 else if(l>mid) return query(rc,mid+1,R,l,r); 68 else return min(query(lc,L,mid,l,r),query(rc,mid+1,R,l,r)); 69 pushup(id); 70 } 71 bool ok(double k,int n){ 72 memset(sum,0,sizeof(sum)); 73 memset(laz,0,sizeof(laz)); 74 build(1,1,n,k); 75 for(int i=1;i<=n;++i){ 76 update(1,1,n,pre[i]+1,i); 77 if(query(1,1,n,1,i)<=k*(i+1)) return 1; 78 } 79 return 0; 80 } 81 int main(){ 82 int t,n,m,i,j; 83 scanf("%d",&t); 84 while(t--){ 85 scanf("%d",&n); 86 memset(x,0,sizeof(x)); 87 for(i=1;i<=n;++i) { 88 scanf("%d",a+i); 89 pre[i]=x[a[i]]; 90 x[a[i]]=i; 91 } 92 93 double l=0,r=1.0; 94 while(abs(l-r)>eps){ 95 double k=(l+r)/2; 96 if(ok(k,n)) r=k; 97 else l=k+eps; 98 } 99 printf("%.10f\n",l); 100 } 101 return 0; 102 }
标签:get pre eps team occurred deb out arch define
原文地址:https://www.cnblogs.com/zzqc/p/9073925.html