码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals)

时间:2018-06-24 18:03:14      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:iterator   splay   lan   前缀   字符   closed   while   ted   uil   

A.String Reconstruction

B. High Load

C. DNA Evolution

题意:给定一个只包含A,T,C,G的字符串S,有如下两种操作

1)修改一个点的字母.

2)给定一个字符串e ($\left | e \right |\leq 10$),生成一个由e重复组成的新串,eee...,问$S_{l..r}$中有几个字母跟这个新的字符串一一对应。

SOL:对于每个字母,用BIT[x][y][L]表示$S_{1..L}$中,所有$\equiv x\left (mod \, y \right )$的位置出现了该字母几次。然后复杂度大概就是$O(100*mlogn)$。

然而比赛的时候由于没有想到树状数组动态更新前缀和,而是用了一个静态数组,强行用定期重构过去了。。复杂度$O(10 * m*\sqrt{n})$,略微有些暴力。

技术分享图片
  1 #include <set>
  2 #include <cmath>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 using namespace std;
  8 const int LEN = 1e5 + 5;
  9 int i, j, k, n, m, s, t, ans, S, top;
 10 char c[LEN], a[LEN], d[LEN];
 11 int f[LEN][15][4];
 12 set <int> st;
 13 typedef set <int> :: iterator iter;
 14 const char to[4] = {A, C, G, T};
 15 int get(char x) {
 16     if (x == A) {
 17         return 0;
 18     } else if (x == C) {
 19         return 1;
 20     } else if (x == G) {
 21         return 2;
 22     } else {
 23         return 3;
 24     }
 25 }
 26 void init() {
 27     for (int i = n; i >= 1; i--) {
 28         for (int j = 1; j <= 10; j++) {
 29             for (int k = 0; k < 4; k++) {
 30                 if (get(c[i]) == k) {
 31                     f[i][j][k] = 1;
 32                 } else {
 33                     f[i][j][k] = 0;
 34                 }
 35                 if (i + j <= n) {
 36                     f[i][j][k] += f[i + j][j][k];
 37                 }
 38             }
 39         }
 40     }
 41 }
 42 int ask(int l, int r, int L) {
 43     int ans = 0;
 44     if (r - l + 1 <= L) {
 45         for (int i = l; i <= r; i++) {
 46             if (c[i] == a[i - l + 1]) {
 47                 ans++;
 48             }
 49         }
 50     } else {
 51         for (int i = 1; i <= L; i++) {
 52             int t = get(a[i]);
 53             ans += f[l + i - 1][L][t];
 54             int k = (r - l + 1 - i) / L + 1;
 55             if (k >= 0 && l + i - 1 + k * L <= n) {
 56                 ans -= f[l + i - 1 + k * L][L][t];
 57             }
 58         }
 59     }
 60     for (iter it = st.begin(); it != st.end(); it++) {
 61         int x = *it, t = get(d[x]);
 62         if (l <= x && x <= r) {
 63             int p = (x - l) % L + 1;
 64             if (get(c[x]) == get(a[p]) && get(a[p]) != t) {
 65                 ans--;
 66             }
 67             if (get(c[x]) != get(a[p]) && get(a[p]) == t) {
 68                 ans++;
 69             }
 70         }
 71     }
 72     return ans;
 73 }
 74 void rebuild() {
 75     for (iter p = st.begin(); p != st.end(); p++) {
 76         int x = *p;
 77         c[x] = d[x];
 78     }
 79     init();
 80     st.clear();
 81 }
 82 int main() {
 83     scanf("%s", c + 1);
 84     n =  strlen(c + 1);
 85     S = sqrt(n) + 200;
 86     init();
 87     scanf("%d", &m);
 88     while (m--) {
 89         int op, l, r;
 90         scanf("%d", &op);
 91         if (op == 2) {
 92             scanf("%d %d", &l, &r);
 93             scanf("%s", a + 1);
 94             int L = strlen(a + 1);
 95             printf("%d\n", ask(l, r, L));
 96         } else {
 97             scanf("%d %s", &l, a + 1);
 98             st.insert(l);
 99             d[l] = a[1];
100             if (st.size() >= S) {
101                 rebuild();
102             }
103         }
104     }
105     return 0;
106 }
View Code

 

Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals)

标签:iterator   splay   lan   前缀   字符   closed   while   ted   uil   

原文地址:https://www.cnblogs.com/NineSwords/p/9221064.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!