[cf787E]Till I Collapse
考虑对询问分块,对于i<K的询问,暴力处理,时间复杂度为o(Kn);对于i>K的询问,发现答案都小于n/K且满足单调性,那么可以二分出每一段相同的答案,时间复杂度为$o(n^{2}log_{2}n/K)$,取K=1000可以通过。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define K 1000 5 int n,ans,c[N],sum[N]; 6 int calc(int k){ 7 memset(sum,0,sizeof(sum)); 8 int ans=0; 9 for(int i=1,j=1;i<=n;i++) 10 if ((++sum[c[i]]==1)&&(++sum[0]>k)){ 11 ans++; 12 sum[0]=1; 13 for(;j<i;j++)sum[c[j]]--; 14 } 15 if (sum[0])ans++; 16 return ans; 17 } 18 int find(int k){ 19 int l=k,r=n; 20 while (l<r){ 21 int mid=(l+r+1>>1); 22 if (calc(mid)<ans)r=mid-1; 23 else l=mid; 24 } 25 return l; 26 } 27 int main(){ 28 scanf("%d",&n); 29 for(int i=1;i<=n;i++)scanf("%d",&c[i]); 30 for(int i=1;i<=min(K,n);i++)printf("%d ",calc(i)); 31 for(int i=K+1;i<=n;){ 32 ans=calc(i); 33 int j=find(i); 34 for(int k=i;k<=j;k++)printf("%d ",ans); 35 i=j+1; 36 } 37 }