• GRE Words Revenge AC自动机 二进制分组


    GRE Words Revenge

    题意和思路都和上一篇差不多。

    有一个区别就是需要移动字符串。关于这个字符串,可以用3次reverse来转换, 前面部分翻转一下, 后面部分翻转一下, 最后整个串翻转一下就好了。

    注意就是多组测试,需要初始化。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define max3(a,b,c) max(a,max(b,c))
     12 #define min3(a,b,c) min(a,min(b,c))
     13 typedef pair<int,int> pll;
     14 const int INF = 0x3f3f3f3f;
     15 const LL mod =  (int)1e9+7;
     16 const int N = 1e7;
     17 struct Node{
     18     static const int m = 2;
     19     static const int KN = N;
     20     int next[KN][m], fair[KN], tot = 0, mark[KN], mark1[KN], root[20], cnt = 0, si[20];
     21     void init(){
     22         tot = cnt = 0;
     23     }
     24     int newtree(){
     25         tot++;
     26         fair[tot] = mark[tot] = mark1[tot] = 0;
     27         memset(next[tot], 0, sizeof(next[tot]));
     28         return tot;
     29     }
     30     void Build(int x){
     31         queue<int> q;
     32         q.push(x);
     33         int pos, p, v;
     34         while(!q.empty()){
     35             pos = q.front(), q.pop();
     36             for(int i = 0; i < m; i++){
     37                 if(!next[pos][i]) continue;
     38                 p = fair[pos]; v = next[pos][i];
     39                 while(p && !next[p][i]) p = fair[p];
     40                 if(p) fair[v] = next[p][i];
     41                 else fair[v] = x;
     42                 q.push(v);
     43                 mark1[v] = mark1[fair[v]] + mark[v];
     44             }
     45         }
     46     }
     47     void Add(char s[], char ch){
     48         root[++cnt] = newtree(); si[cnt] = 1;
     49         int pos = root[cnt];
     50         for(int i = 0; s[i]; i++){
     51             if(!next[pos][s[i]-ch]) next[pos][s[i]-ch] = newtree();
     52             pos = next[pos][s[i]-ch];
     53         }
     54         mark[pos]++;
     55         while(si[cnt] == si[cnt-1]){
     56             Unit(root[cnt-1], root[cnt]);
     57             si[--cnt] *= 2;
     58         }
     59         Build(root[cnt]);
     60     }
     61     int Query(char s[], char ch){
     62         int pos, ret = 0;
     63         for(int id = 1; id <= cnt; id++){
     64             pos = root[id];
     65             for(int i = 0; s[i]; i++){
     66                 while(pos && !next[pos][s[i]-ch]) pos = fair[pos];
     67                 if(pos) pos = next[pos][s[i]-ch];
     68                 else pos = root[id];
     69                 ret += mark1[pos];
     70             }
     71         }
     72         return ret;
     73     }
     74     void Unit(int u, int v){
     75         mark[u] += mark[v];
     76         for(int i = 0; i < m; i++){
     77             if(!next[u][i] || !next[v][i]) next[u][i] += next[v][i];
     78             else Unit(next[u][i], next[v][i]);
     79         }
     80     }
     81 }ac;
     82 char str[N];
     83 set<ULL> st;
     84 ULL v = 0;
     85 int main(){
     86     int n, m, L = 0, len, k;
     87     scanf("%d", &n);
     88     for(int cas = 1; cas <= n; cas++){
     89         L = 0;
     90         ac.init();
     91         st.clear();
     92         scanf("%d", &m);
     93         printf("Case #%d:
    ", cas);
     94         while(m--){
     95             scanf("%s", str);
     96             len = strlen(str+1);
     97             k = L % len;
     98             reverse(str+1, str+1+k);
     99             reverse(str+1+k, str+1+len);
    100             reverse(str+1, str+1+len);
    101             if(str[0] == '+'){
    102                 v = 1;
    103                 for(int i = 1; str[i]; i++){
    104                     v = v * 3 + (str[i]-'0');
    105                 }
    106                 if(st.count(v)) continue;
    107                 else {
    108                     st.insert(v);
    109                     ac.Add(str+1,'0');
    110                 }
    111             }
    112             else {
    113                 L = ac.Query(str+1, '0');
    114                 printf("%d
    ", L);
    115             }
    116         }
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    STM8s窗口看门狗
    开篇
    习题6-8 统计一行文本的单词个数
    习题9-4 查找书籍
    习题9-3 平面向量加法
    习题9-1 时间换算
    习题7-8 字符串转换成十进制整数
    习题8-10 输出学生成绩
    习题7-7 字符串替换
    习题7-6 统计大写辅音字母
  • 原文地址:https://www.cnblogs.com/MingSD/p/9064571.html
Copyright © 2020-2023  润新知