[NOI2017]蚯蚓排队 - hash + 暴力
经过一通复杂度分析后发现,只要暴力做就可以了
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <algorithm> 6 #define LL long long 7 8 using namespace std; 9 10 inline LL read() 11 { 12 LL x = 0, w = 1; char ch = 0; 13 while(ch < '0' || ch > '9') { 14 if(ch == '-') { 15 w = -1; 16 } 17 ch = getchar(); 18 } 19 while(ch >= '0' && ch <= '9') { 20 x = x * 10 + ch - '0'; 21 ch = getchar(); 22 } 23 return x * w; 24 } 25 const int MOD = 998244353; 26 const int MAXS = 1e7 + 10; 27 const int MAXN = 2e5 + 10; 28 const int K = 51; 29 const int mod = 10233333; 30 31 int n, m; 32 33 char s[MAXS]; 34 unsigned LL pre[K * 10], g1[K * 10], g2[K * 10]; 35 int num[MAXN]; 36 int nex[MAXN], ppr[MAXN]; 37 38 void init() 39 { 40 pre[0] = 1; 41 for(int i = 1; i <= K; i++) { 42 pre[i] = pre[i - 1] * 19260817; 43 } 44 } 45 46 int tot = 0; 47 48 struct str { 49 unsigned LL x; 50 LL num; 51 int next; 52 } tmp, e[21000000]; 53 54 struct hashtable { 55 int head[mod]; 56 void add(unsigned LL x, int k) 57 { 58 int s = x % mod; 59 for(int i = head[s]; i; i = e[i].next) { 60 if(e[i].x == x) { 61 e[i].num += k; 62 return; 63 } 64 } 65 e[++tot].num = k, e[tot].x = x; 66 e[tot].next = head[s]; 67 head[s] = tot; 68 } 69 LL cal(unsigned LL x) 70 { 71 int s = x % mod; 72 for(int i = head[s]; i; i = e[i].next) { 73 if(e[i].x == x) { 74 return e[i].num; 75 } 76 } 77 return 0; 78 } 79 } h; 80 81 inline void merge(int a, int b) 82 { 83 int l = 0, r = 0; 84 for(int i = a; i && l < K; i = ppr[i]) { 85 g1[++l] = g1[l - 1] + num[i] * pre[l - 1]; 86 } 87 for(int i = b; i && r < K; i = nex[i]) { 88 g2[++r] = g2[r - 1] * 19260817 + num[i]; 89 } 90 for(int i = 1; i <= l; i++) { 91 for(int j = 1; j <= r; j++) { 92 if(i + j > K) 93 break; 94 95 h.add(g1[i] * pre[j] + g2[j], 1); 96 } 97 } 98 nex[a] = b, ppr[b] = a; 99 } 100 101 inline void split(int a) 102 { 103 int b = nex[a]; 104 int l = 0, r = 0; 105 for(int i = a; i && l < K; i = ppr[i]) { 106 g1[++l] = g1[l - 1] + num[i] * pre[l - 1]; 107 } 108 for(int i = b; i && r < K; i = nex[i]) { 109 g2[++r] = g2[r - 1] * 19260817 + num[i]; 110 } 111 for(int i = 1; i <= l; i++) { 112 for(int j = 1; j <= r; j++) { 113 if(i + j > K) 114 break; 115 h.add(g1[i] * pre[j] + g2[j], -1); 116 } 117 } 118 nex[a] = 0, ppr[b] = 0; 119 } 120 121 void query() 122 { 123 int sum = 0; 124 scanf("%s", s + 1); 125 int k = read(); 126 int len = strlen(s + 1); 127 unsigned LL ha = 0; 128 int ans = 1; 129 // cout<<k<<endl; 130 for(register int i = 1; i <= len; i++) { 131 ha = ha * 19260817 + s[i] - '0'; 132 if(i >= k) { 133 // cout<<ha<<" "<<h.cal(ha)<<endl; 134 ans = 1ll * ans * h.cal(ha) % MOD; 135 // cout<<s[i] - '0'<<" "<<(s[i - k + 1] - '0')<<" "<<ha<<endl; 136 ha = ha - (s[i - k + 1] - '0') * pre[k - 1]; 137 } 138 } 139 printf("%d\n", ans); 140 } 141 142 int main() 143 { 144 // freopen("testdata.in", "r", stdin); 145 // freopen("worm.out", "w", stdout); 146 init(); 147 n = read(), m = read(); 148 for(int i = 1; i <= n; i++) { 149 num[i] = read(); 150 h.add(num[i], 1); 151 } 152 for(int i = 1; i <= m; i++) { 153 int opr = read(); 154 if(opr == 1) { 155 int a = read(), b = read(); 156 merge(a, b); 157 } else if(opr == 2) { 158 int a = read(); 159 split(a); 160 } else { 161 query(); 162 } 163 } 164 } 165 166 /* 167 168 2 2 169 6 6 170 1 1 2 171 3 666666 4 172 173 */