英文作文 思维题

题目链接
在这里插入图片描述
想到了双指针的写法,看了题解之后感觉题解中的算法太妙了,记录一下
需要的是 i < j i < j i<j s [ i ] = s [ j ] s[ i ] = s[ j ] s[i]=s[j] i i i j j j 之间的间隔不超过 k k k ( j − i − 1 j - i - 1 ji1 ≤ \leq k k k )
等价于 s [ i ] = s [ j ] s[ i ] = s[ j ] s[i]=s[j] j − 1 j - 1 j1 ≥ \ge i ≥ \ge j − k − 1 j - k - 1 jk1
枚举 j j j
m p [ ] mp[ ] mp[] 的定义是: m p [ s ] mp[ s ] mp[s] 表示 s s s 前面与 s s s 间隔 k k k 个之内 满足题设的个数
当计算到 s [ j ] s[ j ] s[j] 的时候, m p [ ] mp[ ] mp[] 中存放的是 s [ j − k − 2 ] s[ j - k - 2] s[jk2] s [ j − 1 ] s[ j - 1 ] s[j1] 中每个字符串出现的次数,因为 s [ j − k − 2 ] s[ j - k - 2] s[jk2] 对计算 s [ j ] s[ j ] s[j] 的结果没有贡献,如果不清除其影响反而会影响结果,因此需要先消除其影响,直接在 m p [ ] mp[ ] mp[] 中把 s [ j − k − 2 ] − − s[ j - k - 2 ]-- s[jk2] 即可,那么和当前字符串相同且间隔不超过 k k k 且位于该字符串前面的字符串的个数为 m p [ s [ i ] ] mp[ s[ i ] ] mp[s[i]],在后续的计算中,如果有字符串 s [ p ] s[ p ] s[p] s [ i ] s[i] s[i] 相同,则 s [ p ] s[p] s[p] 的结果需要多加一次 s [ i ] s[i] s[i] 所造成的影响,因此 m p [ s [ i ] ] + + mp[ s[ i ] ]++ mp[s[i]]++,后续也会同上一样被消去的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, k;
const int N = 1e5 + 10;
string s[N];
map<string, int > mp;
int main(){
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin >> n >> k;
	for (int i = 1; i <= n; i++){
		cin >> s[i];
	}
	ll ans = 0; 
	/* 
	 * mp[i] 表示 s 前面与 s 间隔 k 个之内 满足题设的个数
	 * 明显答案就是 mp[i]的累加和
	 * 当计算到 mp[i] 的时候 此时 mp[] 中存放的是 [i - k - 2, i - 1] 中每个字符串出现的次数
	 * 计算 mp[i] 不需要 mp[i - k - 2] 的值 需要去除它对答案的影响 因此 mp[i - k - 2]-- 将该字符串移除
	 * 此后 mp[i] 将影响后续 mp[i + 1, i + k + 1] 的答案 因此 mp[i]++ 表示该字符串在当前区间内多出现了一次
	 * 不得不说 这个算法设计的相当巧妙
	 * 
	*/
	for (int i = 1; i <= n; i++){
		if (i - k - 2 >= 1)mp[s[i - k - 2]]--;
		ans += mp[s[i]];
		mp[s[i]]++;
	}

	cout << ans << "\n";
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值