bzoj3770 疯狂的限制

来源:互联网 发布:跳跃网络300英雄 编辑:程序博客网 时间:2024/05/22 17:44
 疯狂的限制

题目背景:

bzoj3770

分析:算是暴力吧······

 

本来是在做DP来着,然后看到这道题就一起做掉了······做了这道题终于发现,vector是多么有用的东西······我们枚举右端点,那么每次往右移动一个,相当于加入了一个字符,假设当前位置为cur tot[i]表示i ~ cur所形成的子串满足了多少条件,那么新加进来的s[cur + 1]tot的影响其实非常小,他影响的就是所有字符为s[cur + 1]的限制的贡献,(c[i] == s[cur + 1]),如果当前位置cur + 1, 是第ks[cur + 1]出现的位置,那么影响到的贡献位置就是第k - l[i]s[cur + 1]和第k - l[i] + 1s[cur + 1]之间。还有第k - r[i] - 1和第k - r[i]s[cur + 1], 那么我们要做的就是快速找到每一个限制字符为s[cur + 1]的限制,和上面所说的影响到的s[cur + 1]出现的位置,这两者都可以很快的通过vector找到,然后暴力一发,注意边界即可。

注意:

1、关于边界

我们可以预先在存储每一个字符出现位置的vector中预先放入-1,这样就可以很方便的更改开头一段的贡献了

2、关于0

因为可能某些限制的l[i] == 0统计的时候可能会出现问题,所以需要单独进行考虑。

 

Source

/*created by scarlyw*/#include <cstdio>#include <string>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>#include <cctype>#include <vector>#include <set>#include <queue>const int MAXN = 100000 + 10;const int ALP = 26;const int MAXM = 500 + 10;char c;char s[MAXN];int k, len, cnt, ans, l_limit, r_limit;int q[MAXM][3], tot[MAXN];long long final_ans;std::vector<int> query[ALP];std::vector<int> pos[ALP];inline void read_in() {scanf("%s", s), len = strlen(s), cnt = 0;scanf("%d%d%d", &k, &l_limit, &r_limit);for (int i = 1; i <= k; ++i) {static char c[5];scanf("%s%d%d", c, &q[i][1], &q[i][2]);q[i][0] = c[0] - 'a', query[q[i][0]].push_back(i);cnt += (q[i][1] == 0);}}inline void solve() {for (int i = 0; i < ALP; ++i) pos[i].push_back(-1);int ans = 0;for (int i = 0; i < len; ++i) {int c = s[i] - 'a';pos[c].push_back(i), tot[i] += cnt;ans += (tot[i] >= l_limit && tot[i] <= r_limit);for (int k = query[c].size() - 1; k >= 0; --k) {int p = query[c][k], size = pos[c].size() - 1;if (size >= q[p][1] && q[p][1] != 0)for (int j = pos[c][size - q[p][1]] + 1; j <= pos[c][size - q[p][1] + 1]; ++j) {tot[j]++, (tot[j] == l_limit) ? (ans++) : (tot[j] == r_limit + 1 ? ans-- : 0);}if (size > q[p][2])for (int j = pos[c][size - q[p][2] - 1] + 1; j <= pos[c][size - q[p][2]]; ++j) {tot[j]--, (tot[j] == l_limit - 1) ? (ans--) :(tot[j] == r_limit ? ans++ : 0); }}final_ans += (long long)ans;}printf("%lld", final_ans);}int main() {read_in();solve();return 0;}

原创粉丝点击