[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 }
View Code

 

posted @ 2019-07-28 10:30  PYWBKTDA  阅读(212)  评论(0编辑  收藏  举报