Codeforces 1428F Fruit Sequences 乱搞计数

Codeforces 1428F Fruit Sequences

题意

给一个长度为\(n\)\(01\)\(s\)\(f(l,r)\)为区间\([l,r]\)内最长连续\(1\)的个数,计算\(\sum_{i=1}^{n}\sum_{j=i}^{n}f(i,j)\)

\(n \le 5 \cdot 10^5\)

分析

\(pre[i]\)为位置\(i\)之前连续\(1\)的个数,\(suf[i]\)为位置\(i\)之后连续\(1\)的个数,例如\(00111100\)\(pre[4]=2,suf[4]=3\)

\(dp[i]\)\(\sum_{j=1}^{i}f(j,i+suf[i]-1)\),如何计算\(dp[i]\):

  • 首先要加上\(\sum_{j=i-pre[i]+1}^{i}suf[j]\),也就是包含位置\(i\)的一段连续\(1\)的贡献,可以用求和公式化简。
  • 再找到\(i\)之前最近的一个位置\(j\),且\(suf[j]>pre[i]+suf[i]-1\),若找不到则令\(j=0\),加上\(dp[j]+(i-pre[i]-j)\cdot (pre[i]+suf[i]-1)\)

计算完\(dp\)数组后,再枚举端点\(r\),令\(ans\)加上\(\sum_{j=1}^{pre[i]}j\),也就是\(r\)之前连续一段\(1\)的贡献,再类似的找到\(r\)之前最近的一个位置\(j\),且\(suf[j]>pre[r]\),若找不到则令\(j=0\),加上\(dp[j]+(r-pre[r]-j)\cdot pre[r]\)

Code

#include <bits/stdc++.h>
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
using namespace std;
typedef long long ll;
const int N=5e5+10;
int n;
int a[N];
ll f[N];
int pre[N],suf[N],st[N][20];
void init(){
	for(int i=1;i<=n;i++) st[i][0]=suf[i];
	for(int j=1;(1<<j)<=n;j++){
		for(int i=1;i+(1<<j)-1<=n;i++){
			st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
}
int qmx(int l,int r){
	int k=(int)log2(r-l+1);
	return max(st[l][k],st[r-(1<<k)+1][k]);
}
int qy(int x,int num){
    int l=1,r=x;
    while(l<=r){
        int mid=l+r>>1;
        int cnt=qmx(mid,x);
        if(cnt>=num) l=mid+1;
        else r=mid-1;
    }
    return r;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%1d",&a[i]);

    for(int i=1;i<=n;i++){
        if(a[i]) pre[i]=pre[i-1]+1;
    }
    for(int i=n;i>=1;i--){
        if(a[i]) suf[i]=suf[i+1]+1;
    }
    init();
    for(int i=1;i<=n;i++) if(a[i]){
        f[i]=1ll*(2*suf[i]+pre[i]-1)*pre[i]/2;
        int x=pre[i]+suf[i]-1;
        int j=qy(i-pre[i],x+1);
        f[i]+=f[j];
        f[i]+=1ll*(i-pre[i]-j)*x;
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        ans+=1ll*pre[i]*(pre[i]+1)/2;
        int j=qy(i-pre[i],pre[i]+1);
        ans+=f[j];
        ans+=1ll*(i-pre[i]-j)*pre[i];
    }
    cout<<ans<<endl;
    return 0;
}
posted @ 2020-10-19 21:53  xyq0220  阅读(209)  评论(0编辑  收藏  举报