C. Good Subarrays(在线处理) Educational Codeforces Round 93 (Rated for Div. 2)

原题链接:http://codeforces.com/contest/1398/problem/C
在这里插入图片描述
样例:

inputCopy
3
3
120
5
11011
6
600005
outputCopy
3
6
1

题意: 给定好子数组的概念:若子数组的元素之和等于元素个数,那么这个子数组就为好子数组。那么给你一个整数序列字符串,判断该序列有多少个好子数组。

解题思路: 虽然暴力出奇迹,但是这道题不管你怎么暴力,都会TLE(亲测,留下悔恨的泪水)。那么既然不能暴力求解,我们肯定是有巧方法的,什么巧方法呢?就是在线处理,话说在前面,有点难理解。你可能感到很奇怪,这怎么在线处理?我们想想,用子数组总和减去元素个数,如果是为0,那么就是好子数组,如果好子数组中又包含好子数组呢?那么该好子数组是不是可以分为三个好子数组。如果不为0呢?那么我们是不是可以记录这个状态,我们继续往后探索的的时候突然发现子数组总和减去元素个数又为我们上次记录过的状态。那么这个子数组是不是可以拆成我们上次记录过的状态子数组和另一个子数组减元素个数为0的好子数组?(仔细思考这里,非常重要!) 那么我们层层深入,如果一个子数组能这样分为我们已经访问过的状态子数组和一个好子数组,那么不就实现在线处理了吗?因为现在我们只要遍历一遍数组了,其他的子数组我们就可以利用当前已经记录的子数组分解获得。那么时间复杂度就大大减小了。OK,那么我们怎么记录之前状态呢?这里就要使用map容器了,我们标记所有计算的差值状态,利用sum统计值即可。若之前标记过两次,说明我们可以拆成两种情况:一个差值为标记过的子数组和一个好子数组。OK,具体看代码。我贴了详细注释,若还不太明白,欢迎评论区留言。

AC代码:

/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>	//POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int main(){
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	int t,n;
	string str;
	while(cin>>t){
		while(t--){
			cin>>n>>str;
			ll sum=0,cnt=0;
			map<int,int> p;
			p[0]++;//这个状态是属于好子数组的状态,我们自然得标记为1.
			rep(i,0,n-1){
				sum+=str[i]-'0';
				cnt+=p[sum-(i+1)];//加上之前出现过的状态。这即是我们可以分解的好子数组数量。
				p[sum-(i+1)]++;//当前状态出现,叠加1.
			}
			cout<<cnt<<endl;
		}
	}
	return 0;
}

posted @   unique_pursuit  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示