codeforces 1168B Codeforces Round #562 (Div. 1) B. Good Triple

题目链接:http://codeforces.com/problemset/problem/1168/B

Toad Rash has a binary string ss. A binary string consists only of zeros and ones.

Let nn be the length of ss.

Rash needs to find the number of such pairs of integers ll, rr that 1≤l≤r≤n1≤l≤r≤n and there is at least one pair of integers xx, kk such that 1≤x,k≤n1≤x,k≤n, l≤x<x+2k≤rl≤x<x+2k≤r, and sx=sx+k=sx+2ksx=sx+k=sx+2k.

Find this number of pairs for Rash.

Input

The first line contains the string ss (1≤|s|≤3000001≤|s|≤300000), consisting of zeros and ones.

Output

Output one integer: the number of such pairs of integers ll, rr that 1≤l≤r≤n1≤l≤r≤n and there is at least one pair of integers xx, kk such that 1≤x,k≤n1≤x,k≤n, l≤x<x+2k≤rl≤x<x+2k≤r, and sx=sx+k=sx+2ksx=sx+k=sx+2k.

Examples

input

010101

output

3

input

11001100

output

0

Note

In the first example, there are three ll, rr pairs we need to count: 11, 66; 22, 66; and 11, 55.

In the second example, there are no values xx, kk for the initial string, so the answer is 00.

题意概述:给一串由0和1构成的字符串S,设有一个区间[l,r],在这个区间里至少有一组x和k,使Sx,Sx+k,Sx+2k是一样的数(同为0或同为1),求有多少个这样的区间

解题思路:从前向后找,每一个字符Si都找一个符合Si,Si+k,Si+2k相等的,当l等于Si这个可以组成的区间数为(n-Si+2k),需要注意的是前面的S0至Si-1如果找到的最小区间如果大于Si+2k,需要更新前面的答案,需要注意的是,如果现在的i已经大于前面的值了需要更新,否则会作很多无意义的运算,时间超限。

#include<iostream>
#include<queue>
#include<cstring> 
#include<cmath>
#include<map>
#include<algorithm>
#define up(i,x,y) for(i=x;i<y;i++)  
#define down(i,x,y) for(i=x;i>=y;i--)  
#define MAX(a,b) a>b?a:b
#define MIN(a,b) a<b?a:b
#define MAX(a,b,c) (a>b?(a>c?a:c):(b>c?b:c))
#define MIN(a,b,c) (a<b?(a<c?a:c):(b<c?b:c))
using namespace std;

typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 100;
const int MAXN = 2750131;
ll T,n,m,i,j;
ll gcd(ll p,ll q)
{return q==0?p:gcd(q,p%q);}

int main()
{
	bool b[2000];
	int sum[300005];
	int max;
	string s;
	cin>>s; 
	n=s.length();
	max=0;
	ll ans=0;
	for(i=0;i<n;i++){
		sum[i]=n;
		for(j=1;j*2+i<n;j++){
			if(s[i]==s[i+j]&&s[i]==s[i+j*2]){
				while(sum[max]<i)
				{
					max++;
				}
				for(int k=max;k<=i;k++){
					if(sum[k]>(j*2+i)){
						ans+=sum[k]-(j*2+i);
						sum[k]=(j*2+i);
					}
				}
				if(j==1){
					max=i;
				}
				break;
			}
		}
	}
	cout<<ans<<endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值