0
点赞
收藏
分享

微信扫一扫

TC TCO2015R2D(BalancedSubstrings-天平平衡)

zhyuzh3d 2022-11-14 阅读 63


Problem Statement

 

This problem deals with binary strings: strings in which each character is either '0' or '1'. The characters are interpreted as zeros and ones.

Assume that we have a binary string of length N. Imagine the string as a horizontal lever of length N-1. The weight of the lever is negligible. On the lever, the points with integer coordinates are numbered from 0 (one end of the lever) to N-1 (the other end). Our string represents the distribution of weights on this lever. For each i, if character i of our string is '0', the corresponding point is empty, and if the character is '1', there is a unit weight at that point. Suppose that we place a fulcrum under the point number i. We say that element i of the string is a balance point if the lever is balanced on the fulcrum: the moments of force on either side cancel each other out. A string is called a balanced string if it has at least one balance point. Note that the balance point must be one of the marked points (see examples below).

A formal definition follows. For each valid index i we can compute the torque at i as follows:

  1. For each element to the left of i, take its value, multiply it by its distance from i, and add all those results together to obtain the value A.
  2. For each element to the right of i, take its value, multiply it by its distance from i, and add all those results together to obtain the value B.
  3. The torque at i is computed as (A - B).

We say that index i is a balance point if the torque at i is exactly zero. (Note that the value of the element at index i isn't used in the definition and therefore it can be arbitrary.)

For example, the string "10100001" is a balanced string. Its balance point is the (0-based) index i=3. If we put the fulcrum under the lever at this position, we see "101" to the left and "0001" to the right. On the left side we get A = 1*3 + 0*2 + 1*1 = 4, and on the right side we get B = 0*1 + 0*2 + 0*3 + 1*4 = 4, hence A-B is exactly zero.

The string "0001" is also a balanced string, as its last character is a balance point. The string "11" is not a balanced string, as neither of its two characters is a balance point.

You are given a string s that is a binary string. Return the number of nonempty substrings of s that are balanced.

Substrings that consist of the same characters but occur elsewhere in s are considered different substrings. If they are balanced, each of them should be counted separately. For example, the string "00000" contains four distinct occurrences of the substring "00".

Definition

 

Limits

 

Constraints

-

s will have between 1 and 2,500 characters, inclusive.

-

Each character in s will be '0' or '1'.

Examples

0)

 

 

1)

 

 

2)

 

 

3)

 

 

4)

 

 

Class:

BalancedSubstrings

Method:

countSubstrings

Parameters:

string

Returns:

int

Method signature:

int countSubstrings(string s)

(be sure your method is public)

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.     



法一:

预处理从a[i,j]表示以i为支点到j对天平的贡献,

枚举支点 O(n^3)

二分支点 O(n^2logn)

固定左端点,随右端点增大向右推支点 O(n^2)

法二:

根据力矩公式,向右推一个支点,左右力矩和差减小sum(区间内1的个数),取Mod sum即可.

注意全为0的情况




#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<string>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (2500+10)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
class BalancedSubstrings
{
public:
ll a[MAXN][MAXN],b[MAXN][MAXN];
int sum[MAXN][MAXN];
bool is[MAXN][MAXN];
bool v[MAXN];
int countSubstrings(string s)
{
int n=s.length();
MEM(a) MEM(b) MEM(is)
MEM(v) MEM(sum)
Rep(i,n) v[i]=(s[i]=='1');

Rep(i,n)
Fork(j,i,n-1) sum[i][j]=sum[i][j-1]+(s[j]-'0');



Rep(i,n)
Fork(j,i+1,n-1) a[i][j]=a[i][j-1]+(j-i)*(s[j]-'0');

Rep(i,n)
RepD(j,i-1) a[i][j]=a[i][j+1]-(i-j)*(s[j]-'0');
int ans=0;
Rep(i,n)
{
Fork(j,i,n-1) {
if (i==j) {++ans;is[i][j]=1;continue;}
if (is[i][j-1]&&(!v[j])) {++ans;is[i][j]=1;continue;}
if (is[i+1][j]&&(!v[i])) {++ans;is[i][j]=1;continue;}
if (i<j-1&&is[i+1][j-1]&& (!(v[i]^v[j])) ) {++ans;is[i][j]=1;continue;}

int tot=sum[i][j];
if (a[i][j]%tot==0)
{
++ans;
is[i][j]=1;
continue;
}

}
}
return ans;


}
}S;
string s;
int main()
{
freopen("s.out","r",stdin);
// freopen(".out","w",stdout);

cin>>s;
cout<<S.countSubstrings(s)<<endl;

return 0;
}






举报

相关推荐

0 条评论