3798. 【NOIP2014模拟8.22】临洮巨人 (Standard IO)

本文探讨了一种高效的算法,用于解决特定条件下的子串计数问题。通过对字符串进行预处理,使用前缀和的概念,结合动态规划思想,实现了快速查找满足条件的子串数量。算法针对不同规模的数据进行了优化,确保在大数据量下仍能保持良好的性能。

 

Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits  

Description

Input

一行一个由大写字母A到L组成的字符串S。

Output


注意是输出子串的个数。

Sample Input

ABACABA

Sample Output

2
样例解释:BAC和CAB
 

Data Constraint

对于30%的数据,|S|<=100。
对于70%的数据,|S|<=1000。
对于100%的数据,1<=|S|<=1000000。

Source / Author: 常州高级中学NOIP2014夏令营 lintaojuren

 

 

反思:

比赛的时候就伪AC了, 自以为万无一失(打了两个程序, 一个暴力优化, 一个Ac版, 已经对了拍), 可两个程序都是错的, 错的一起错。

这个故事告诉我们对拍程序一定要是纯暴力程序。

思路 : 

回想之前做过类似的题目, 对于要求两种元素在一段区间内数目相当, 我们把其中一种元素设为1, 另一个元素设为-1, 做一遍前缀和, 若i ~ j合法, 则pre[j] - pre[i - 1] = 0

可是现在我们有三种元素了。

那么把问题拆开 , 分别讨论ab和ac的相同段。

 

浅层思考, 对于结尾i, 把ab和ac相同段的开头列出, 若有相同, 则a=b=c。

可这样太慢了, 空间也不允许。

瓶颈在于不能利用前面已经获得的信息。

那么我们能不能对于结尾i, 找到距离i最近的j使其a = b = c, 然后利用j的信息呢?

可以。设cnt[i]为到i有多少a=b=c端点, cnt[i] = cnt[j] + 1, ans += cnt[i]。

时间复杂度比正解稍慢。

#include<bits/stdc++.h>
#define open(x) freopen(x".in", "r", stdin);freopen(x".out", "w", stdout)
#define mem(a, b) memset(a, b, sizeof(a))
#define mcy(a, b) memcpy(a, b, sizeof(a))
#define pf printf
#define sf scanf
#define fo(i, a, b) for(register int i = a; i <= b; ++i) 
#define fown(i, a, b) for(register int i = a; i >= b; --i)
#define em(p, x) for(ll p=tail[x];p;p=e[p].fr)
#define ll long long
#define wt(a, c, d, s) fo(i, c, d) pf((s), a[i]); puts("")
#define rd(a, c, d) fo(i, c, d) in(a[i])
#define N 2000010
#define inf 2147483647
#define mod (ll)(1e9 + 7)
using namespace std;

template<class T> 
T in(T &x) {
	x=0;
	char ch = getchar(); ll f = 0;
	while(ch < '0' || ch > '9') f |= ch == '-', ch = getchar();
	while(ch >= '0' && ch <= '9') x = (x<<1) + (x<<3) + ch - '0', ch = getchar();
	x = f ? -x : x;
	return x;
}

const ll fix = 1000001;

int n;
int lst1[N], lst2[N];
ll f1[N], f2[N], ans, pre1[N], pre2[N], cnt[N];
char s[N];

int main() {
	open("gaint");
	sf("%s\n", s + 1);
	n = strlen(s + 1);
	mem(lst1, 255), mem(lst2, 255);
	f1[0] = f2[0] = fix;
	lst1[f1[0]] = lst2[f2[0]] = 0;
	pre1[0] = 0, pre2[0] = 0;
	fo(i, 1, n) {
		f1[i] = f1[i - 1], f2[i] = f2[i - 1]; 
		if(s[i] == 'A')
		
			f1[i]++, f2[i]++;
			
		else if(s[i] == 'B') 
			f1[i]--;
		else if(s[i] == 'C')
			f2[i]--;
		int p = lst1[f1[i]], q = lst2[f2[i]];
		while(p >= 0 && q >= 0) {
			if(p == q) break;
			if(i - p > i - q) {
				if(pre2[q] >=0)
				q = pre2[q]; else break;
			} else {if(pre1[p] >= 0)p = pre1[p]; else break;}
		}
		if(p == q && p >= 0) {
			cnt[i] = cnt[p] + 1;
			ans += cnt[i]; //add the ans before
		}
		pre1[i] = lst1[f1[i]], pre2[i] = lst2[f2[i]];
	
		lst1[f1[i]] = i, lst2[f2[i]] = i;
	}
	
	printf("%lld\n", ans);
	return 0;
}

 

 

 

基于遗传算法的微电网调度(风、光、蓄电池、微型燃气轮机)(Matlab代码实现)内容概要:本文档介绍了基于遗传算法的微电网调度模型,涵盖风能、太阳能、蓄电池和微型燃气轮机等多种能源形式,并通过Matlab代码实现系统优化调度。该模型旨在解决微电网中多能源协调运行的问题,优化能源分配,降低运行成本,提高可再生能源利用率,同时考虑系统稳定性与经济性。文中详细阐述了遗传算法在求解微电网多目标优化问题中的应用,包括编码方式、适应度函数设计、约束处理及算法流程,并提供了完整的仿真代码供复现与学习。此外,文档还列举了大量相关电力系统优化案例,如负荷预测、储能配置、潮流计算等,展示了广泛的应用背景和技术支撑。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事微电网、智能电网优化研究的工程技术人员。; 使用场景及目标:①学习遗传算法在微电网调度中的具体实现方法;②掌握多能源系统建模与优化调度的技术路线;③为科研项目、毕业设计或实际工程提供可复用的代码框架与算法参考; 阅读建议:建议结合Matlab代码逐段理解算法实现细节,重点关注目标函数构建与约束条件处理,同时可参考文档中提供的其他优化案例进行拓展学习,以提升综合应用能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值