Good Triple CodeForces - 1169D (arithmetic sequence)

Effect: Given 01 strings, find the number of intervals $ [l, r] $, such that there is a positive integer $ x, k $ meet $ 1 \ le x, k \ le n, l \ le x <x + 2k \ le r, s_x = s_ {x + k} = s_ {x + 2k} $.

 

0 and 1 considered separately, then the problem is transformed into a given number of intervals required arrangement comprising arithmetic sequence can be determined by the position of the minimum arithmetic sequence CF 452F Permutation method, and then easily able to account for the answer.

Complexity is $ O (n) $ of

#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#include <bitset>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
#define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, P2 = 998244353, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
//head


const int N = 1e6+10;
int n, f[N];
char s[N];
vector<int> g[2];

int main() {
	scanf("%s", s+1);
	n = strlen(s+1);
	REP(i,1,n) g[s[i]-'0'].pb(i);
	REP(i,0,1) if (g[i].size()>=3) {
		int sz = g[i].size();
		REP(j,1,sz-2) {
			for (int k=j+1; k<min(sz,j+5); ++k) {
				int r = 2*g[i][k]-g[i][j], l = 2*g[i][j]-g[i][k];
				if (1<=r&&r<=n&&s[r]==s[g[i][j]]) { 
					f[r] = max(f[r], g[i][j]);
				}
				if (1<=l&&l<=n&&s[l]==s[g[i][j]]) {
					f[g[i][k]] = max(f[g[i][k]], l);
				}
			}
		}
	}
	REP(i,1,n) f[i] = max(f[i-1], f[i]);
	ll ans = 0;
	REP(i,1,n) ans += f[i];
	printf("%lld\n", ans);
}

 

Guess you like

Origin www.cnblogs.com/uid001/p/10941847.html