P6273 [eJOI2017] 魔法 题解
5k_sync_closer · · 题解
提供一个小常数
思路
根据题意,子串
维护前缀和
把
任意选择一个
维护
考虑对于每个
正序枚举 map,计算出 map 中 map。
代码
一些细节:
- 注意到
vector自带比较运算符,所以可以开map<vector<int>, int>。 - 注意到需要将字符作为
vector的下标,所以需要离散化。 - 注意到
\forall x\in [1,n],v_x 只会用一次,所以可以动态更新v_x 。 - 注意到存在
l=1,l-1=0 的情况,所以需要事先将全0 集合加入map。 - 注意取模。注意答案开
long long。
感觉其他题解都把代码写复杂了。
#include <bits/stdc++.h>
#define h(x) lower_bound(a, a + k, x) - a
using namespace std;
vector<int> v;map<vector<int>, int> m;
int n, k;long long q;char a[100050], s[100050];
int main()
{
scanf("%d%s", &n, s);strcpy(a, s);sort(a, a + n);
m[v = vector<int>(k = unique(a, a + n) - a, 0)] = 1;
for (int i = 0; i < n; ++i)
{
if (s[i] != a[0]) ++v[h(s[i])];
else {for (auto &x : v) --x;++v[0];}
(q += m[v]++) %= 1000000007;
}
return printf("%lld", q), 0;
}
目前最优解 rk 1。