洛谷P5112 FZOUTSY

卡map还行.....手写hash表即可。

我一开始以为这个k会变......在sam上想各种奇技淫巧。

k不变就是问一段区间有多少对长度为k的子串相同。

然后hash把子串转化为数字,就是区间有多少对相同数字。直接莫队即可。

 

  1 #include <bits/stdc++.h>
  2 
  3 inline void read(int &x) {
  4     x = 0;
  5     char c = getchar();
  6     while(c < '0' || c > '9') c = getchar();
  7     while(c >= '0' && c <= '9') {
  8         x = x * 10 + c - 48;
  9         c = getchar();
 10     }
 11     return;
 12 }
 13 
 14 typedef long long LL;
 15 typedef unsigned long long uLL;
 16 const int N = 3000010;
 17 const uLL B = 13331;
 18 
 19 uLL h[N], pw[N];
 20 std::map<uLL, int> mp;
 21 int n, k, val[N], fr[N], bin[N];
 22 char str[N];
 23 LL ans[N], Ans;
 24 
 25 namespace Map {
 26     const int mod = 10000010;
 27     struct Edge {
 28         uLL val;
 29         int num, nex;
 30     }edge[N]; int tp;
 31     int e[mod], num;
 32     inline int insert(uLL v) {
 33         int x = v % mod;
 34         for(int i = e[x]; i; i = edge[i].nex) {
 35             if(edge[i].val == v) return edge[i].num;
 36         }
 37         edge[++tp].val = v;
 38         edge[tp].num = ++num;
 39         edge[tp].nex = e[x];
 40         e[x] = tp;
 41         return num;
 42     }
 43 }
 44 
 45 struct Ask {
 46     int l, r, id;
 47     inline bool operator <(const Ask &w) const {
 48         if(fr[l] != fr[w.l]) return l < w.l;
 49         return r < w.r;
 50     }
 51 }ask[N];
 52 
 53 inline uLL Hash(int l, int r) {
 54     return h[r] - h[l - 1] * pw[r - l + 1];
 55 }
 56 
 57 inline void getHash() {
 58     pw[0] = 1;
 59     for(register int i = 1; i <= n; i++) {
 60         pw[i] = B * pw[i - 1];
 61         h[i] = h[i - 1] * B + str[i];
 62     }
 63     for(register int i = 1; i + k - 1 <= n; i++) {
 64         uLL t = Hash(i, i + k - 1);
 65         //printf("i = %d t = %llu \n", i, t);
 66         val[i] = Map::insert(t);
 67         //printf("val %d = %d \n", i, val[i]);
 68     }
 69     return;
 70 }
 71 
 72 inline void add(int x) {
 73     Ans += bin[val[x]];
 74     bin[val[x]]++;
 75     return;
 76 }
 77 
 78 inline void del(int x) {
 79     bin[val[x]]--;
 80     Ans -= bin[val[x]];
 81     return;
 82 }
 83 
 84 int main() {
 85     int m;
 86     read(n); read(m); read(k);
 87     scanf("%s", str + 1);
 88     int T = (double)n / sqrt(m);
 89     for(register int i = 1; i <= m; i++) {
 90         read(ask[i].l); read(ask[i].r);
 91         ask[i].r = std::min(ask[i].r, n - k + 1);
 92         ask[i].id = i;
 93     }
 94     for(register int i = 1; i <= n; i++) fr[i] = (i - 1) / T + 1;
 95     std::sort(ask + 1, ask + m + 1);
 96     getHash();
 97 
 98     int l = 1, r = 1; bin[val[1]] = 1;
 99     for(register int i = 1; i <= m; i++) {
100         if(ask[i].l >= ask[i].r) {
101             ans[ask[i].id] = 0;
102             continue;
103         }
104         while(ask[i].l < l) {
105             add(--l);
106         }
107         while(r < ask[i].r) {
108             add(++r);
109         }
110         while(l < ask[i].l) {
111             del(l++);
112         }
113         while(ask[i].r < r) {
114             del(r--);
115         }
116         ans[ask[i].id] = Ans;
117     }
118     for(register int i = 1; i <= m; i++) printf("%lld\n", ans[i]);
119     return 0;
120 }
AC代码

 

posted @ 2019-03-18 08:53  huyufeifei  阅读(128)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜