TC TCO2015R2D(BalancedSubstrings-天平平衡)

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

 
Class:BalancedSubstrings
Method:countSubstrings
Parameters:string
Returns:int
Method signature:int countSubstrings(string s)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):256
Stack limit (MB):256

Constraints

-s will have between 1 and 2,500 characters, inclusive.
-Each character in s will be '0' or '1'.

Examples

0) 
 
"011"
Returns: 4
The balanced substrings in this case are {"0", "1", "1", "01"}
1) 
 
"10111"
Returns: 10
The balanced substrings are {"1", "0", "1", "1", "1", "10", "01", "101", "111", "0111"}
2) 
 
"00000"
Returns: 15
All substrings in this case are balanced.
3) 
 
"0000001000000"
Returns: 91
4) 
 
"100110001001"
Returns: 49

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值