题目

  点这里看题目。

分析

  设前缀和\(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. 梳理继承中的has a和is a

    面向对象中的继承问题,研究了一天 ,简单梳理下其中最重要的has a和is a 1.has a 一个类中使用了另一个类中的自定义的类型 这里Student中使用了Book 和 computer2.类型 ...

  2. Excel导出到DataSet

    #region 导入excel 返回Dataset public DataSet ExecleDataSet(string filename, string file, string Type) { ...

  3. poj2391 最大流+拆点+二分答案+Floyd

    Ombrophobic Bovines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19553   Accepted: 4 ...

  4. Text Reverse(hdu1062)

    输入方式:先输入整数,再循环输入字符串. 思考:字符串中有空格.那么要在字符串大循环输入前,首先,用"getchar()"函数读取scanf_s()函数缓冲区的空格或者空行或者换行 ...

  5. 记一次 React Native 大版本升级过程——从0.40到0.59

    去年把公司几个react native 相关的项目升级了下,已经过去一段时间了,这里系统整理下之前的整个过程. 背景 之前到公司的时候发现公司用的还是0.40的版本,据了解,当时项目做的比较早,导航用 ...

  6. 监控-zabbix

    1:什么是监控? 监控:安防的监控  看监控,事后追责 linux监控: 事前预警,数据分析 2:常见的linux监控命令 cpu             1 top 2 htop 3 uptime ...

  7. ES[7.6.x]学习笔记(十)聚合查询

    聚合查询,它是在搜索的结果上,提供的一些聚合数据信息的方法.比如:求和.最大值.平均数等.聚合查询的类型有很多种,每一种类型都有它自己的目的和输出.在ES中,也有很多种聚合查询,下面我们看看聚合查询的 ...

  8. PAT 1033 To Fill or Not to Fill (25分) 贪心思想

    题目 With highways available, driving a car from Hangzhou to any other city is easy. But since the tan ...

  9. 07 . Python3函数

    Python3函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.Python提供了许多内建函数,比如print().我们可以直接调用 ...

  10. 【Mybatis】mybatis3入门

    mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...