题目

  点这里看题目。

分析

  设前缀和\(s_r=\sum_{i=1}^r [S_i='1']\)

  考虑满足要求的子串\((l,r]\)的要求:

\[\exists k\in N_+, r-l=k(s_r-s_l)
\]

  单独计算并不好算,考虑一个分块的优化。设置阈值\(T\)。

  对于\(1\le k\le T\)的\(k\),对要求进行变形:

\[r-l=k(s_r-s_l)\Rightarrow ks_r-r=ks_l-l
\]

  设\(f(i,k)=ks_i-i\),那么当\(k\)固定的时候,设\(c(x,k)\)为\(f(i,k)=x\)的数量,答案就是:

\[\sum_{k=1}^T\sum_{x=0}^{nT}\binom{c(x,k)}{2}
\]

  后面的那个循环,由于有值的\(c(x,k)\)不会超过\(n\)个,因此这一部分可以\(O(nT)\)计算。

  对于\(T< k\le n\)的\(k\),继续变形:

\[r-l=k(s_r-s_l)\Rightarrow \frac{r-l}k=s_r-s_l
\]

  由于\(k>T\),所以有\(s_r-s_l< \frac nT\)。也就是说,这种情况下子串内 1 的数量比较少。那么我们就可以直接枚举子串的起点(即式子中的\(l\))和子串内 1 的数量来计算。

  当我们确定了 1 的数量的时候,我们也就可以确定此时右端点的范围\((x,y]\),那么也就知道了区间长度的范围\((x-i,y-i]\)。此时的询问就变成求区间内的\(k\)的倍数的数量,可以\(O(1)\)。

  需要注意的是,由于这一部分不能前面的记重,因此应该满足:

\[\begin{aligned}
k>T&\Rightarrow \frac{r-l}{s_r-s_l}>T\\
&\Rightarrow r-l>T(s_r-s_l)
\end{aligned}\]

  即区间长度必须大于\(T(s_r-s_l)\),特判一下即可。

  时间复杂度是\(O(nT+\frac{n^2}T)\),取\(T=\sqrt n\)最优。

代码

#include <cmath>
#include <cstdio>
#include <cstring> typedef long long LL; const int MAXN = 2e5 + 5, MAXT = 505; template<typename _T>
void read( _T &x )
{
x = 0;char s = getchar();int f = 1;
while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
x *= f;
} template<typename _T>
void write( _T x )
{
if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
if( 9 < x ){ write( x / 10 ); }
putchar( x % 10 + '0' );
} template<typename _T>
_T MAX( const _T a, const _T b )
{
return a > b ? a : b;
} int buc[MAXN * MAXT];
int s[MAXN], nxt[MAXN];
int N, T;
char S[MAXN]; int main()
{
LL ans = 0;
scanf( "%s", S + 1 ), N = strlen( S + 1 ), T = ceil( sqrt( N ) );
for( int i = 1 ; i <= N ; i ++ ) s[i] = s[i - 1] + S[i] - '0';
if( s[N] == 0 ) { puts( "0" ); return 0; }
for( int i = N ; ~ i ; i -- )
{
if( s[i] ^ s[i + 1] ) nxt[i] = i + 1;
else nxt[i] = nxt[i + 1];
}
for( int k = 1, t ; k <= T ; k ++ )
{
for( int i = 0 ; i <= N ; i ++ ) buc[s[i] * k - i + N] ++;
for( int i = 0 ; i <= N ; i ++ ) t = buc[s[i] * k - i + N], ans += 1ll * t * ( t - 1 ) / 2, buc[s[i] * k - i + N] = 0;
}
int l, r, tl, tr;
for( int i = 0 ; i < N ; i ++ )
{
l = i, r = nxt[i];
for( int k = 1 ; k <= N / T && s[i] + k <= s[N] ; k ++ )
{
l = nxt[l], r = nxt[r];
tr = r - i - 1, tl = l - i;
tl = MAX( tl, k * T + 1 );
if( tl <= tr ) ans += tr / k - ( tl - 1 ) / k;
}
}
write( ans ), putchar( '\n' );
return 0;
}

[CF1270F]Awesome Substrings的更多相关文章

  1. [LeetCode] Unique Substrings in Wraparound String 封装字符串中的独特子字符串

    Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz" ...

  2. Leetcode: Unique Substrings in Wraparound String

    Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz" ...

  3. CSU-1632 Repeated Substrings (后缀数组)

    Description String analysis often arises in applications from biology and chemistry, such as the stu ...

  4. CF451D Count Good Substrings (DP)

    Codeforces Round #258 (Div. 2) Count Good Substrings D. Count Good Substrings time limit per test 2 ...

  5. LA4671 K-neighbor substrings(FFT + 字符串Hash)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...

  6. 后缀数组---New Distinct Substrings

    Description Given a string, we need to find the total number of its distinct substrings. Input T- nu ...

  7. Codeforces Round #258 D Count Good Substrings --计数

    题意:由a和b构成的字符串,如果压缩后变成回文串就是Good字符串.问一个字符串有几个长度为偶数和奇数的Good字串. 分析:可知,因为只有a,b两个字母,所以压缩后肯定为..ababab..这种形式 ...

  8. SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转

    694. Distinct Substrings Problem code: DISUBSTR   Given a string, we need to find the total number o ...

  9. Codeforces Round #306 (Div. 2) A. Two Substrings 水题

    A. Two Substrings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/550/pro ...

随机推荐

  1. zz MySQL redo log及recover过程浅析

    原作地址:http://www.cnblogs.com/liuhao/p/3714012.html 写在前面:作者水平有限,欢迎不吝赐教,一切以最新源码为准. InnoDB redo log 首先介绍 ...

  2. linux添加策略路由python脚本(待完善)

    #! _*_ coding:utf-8 _*_ import os,sys,re,fileinput,socket device_list = [] ip_list = [] ip_end = [] ...

  3. [工具推荐]004.EXE签名工具SignTool使用教程

    数字证书,真是个神奇的东西,可以保证软件不被修改,可以表明文件的发布日期,最重要的,可以很大程度的减少杀毒软件的误报,当然,这就要使用可信任的机构颁发的证书了. 现在要说的不是申请证书,而是如何制作自 ...

  4. Robot Framework(15)- 扩展关键字

    如果你还想从头学起Robot Framework,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1770899.html 前言 什么是扩展 ...

  5. Java中方法的重载与重写

    1.方法的名字和参数列表称为方法的签名:每个方法具有唯一与其对应的签名: 2.方法的重载:在某个类中,存在具有多个相同名字不同参数列表的方法,称之为重载: 被重载的方法必须改变参数列表(参数个数或类型 ...

  6. 树莓派3B安装ubuntu mate系统后无法联网

    问题描述:在安装系统的初始化操作时,可以联网,如下图所示: 但是在系统安装结束后,wifi标志处无信号,无法搜索wifi信号. 解决方法:实测有效 直接打开终端(ctrl+alt+t),执行指令:su ...

  7. Spring boot Sample 005之spring-boot-profile

    一.环境 1.1.Idea 2020.1 1.2.JDK 1.8 二.目的 通过yaml文件配置spring boot 属性文件 三.步骤 3.1.点击File -> New Project - ...

  8. Rocket - devices - PLIC

    https://mp.weixin.qq.com/s/FR3yeLLBqy0n-fflw-ATgg 简单介绍TLPLIC的实现. 1. GatewayPLICIO PLIC是Platform-Leve ...

  9. Rocket - util - MaskGen

    https://mp.weixin.qq.com/s/_aJqf1cFJDK5RVRBhxTWOw   介绍MaskGen的实现.   ​​   1. 基本介绍   给定总线宽度beatBytes,根 ...

  10. C# winform 学习(三)

    目标 1.windows程序简介 2.窗体的常用属性和事件 3.显示消息框 4.多窗体应用 一.程序简介 1.特点:所见即所得,通过事件实现用户与界面的交互 2.程序结构 1)窗体文件(每个窗体至少有 ...