围观了叉姐的代码,hash对于解串类题目真的好灵活, 又涨姿势了 ==。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> #include <bitset> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::stringstream; using std::make_pair; using std::getline; using std::greater; using std::endl; using std::multimap; using std::deque; using std::unique; using std::lower_bound; using std::random_shuffle; using std::bitset; using std::upper_bound; using std::multiset; typedef long long LL; typedef unsigned long long ULL; typedef unsigned UN; typedef pair<int, int> PAIR; typedef multimap<int, int> MMAP; typedef LL TY; typedef long double LF; const int MAXN(100010); const int MAXM(55); const int MAXE(200010); const int MAXK(6); const int HSIZE(13131); const int SIGMA_SIZE(26); const int MAXH(20); const int INFI((INT_MAX-1) >> 1); const ULL BASE(31); const LL LIM(1e13); const int INV(-10000); const int MOD((1 << 30)-1); const double EPS(1e-7); const LF PI(acos(-1.0)); template<typename T> inline void checkmax(T &a, T b){if(b > a) a = b;} template<typename T> inline void checkmin(T &a, T b){if(b < a) a = b;} template<typename T> inline T ABS(const T &a){return a < 0? -a: a;} ULL hash1[30], hash2[30]; int arr1[100010], arr2[25010]; int ans[100010], ca; int main() { int n, K, s; while(~scanf("%d%d%d", &n, &K, &s)) { for(int i = 1; i <= n; ++i) scanf("%d", arr1+i); for(int i = 1; i <= K; ++i) scanf("%d", arr2+i); if(n < K) { printf("0\n"); continue; } ULL sub = 1; for(int i = 1; i < K; ++i) sub *= BASE; memset(hash2, 0, sizeof(hash2)); for(int i = 1; i <= K; ++i) { for(int j = 0; j < s; ++j) hash2[j] *= BASE; ++hash2[arr2[i]-1]; } memset(hash1, 0, sizeof(hash1)); for(int i = 1; i < K; ++i) { for(int j = 0; j < s; ++j) hash1[j] *= BASE; ++hash1[arr1[i]-1]; } ca = 0; for(int i = K; i <= n; ++i) { for(int j = 0; j < s; ++j) hash1[j] *= BASE; ++hash1[arr1[i]-1]; int t1 = s-1, t2 = s-1; while(true) { while(t1 >= 0 && hash1[t1] == 0) --t1; while(t2 >= 0 && hash2[t2] == 0) --t2; if(t1 == -1 && t2 == -1) break; if(t1 == -1 || t2 == -1) break; if(hash1[t1] != hash2[t2]) break; --t1; --t2; } if(t1 == -1 && t2 == -1) ans[ca++] = i-K+1; hash1[arr1[i-K+1]-1] -= sub; } printf("%d\n", ca); for(int i = 0; i < ca; ++i) printf("%d\n", ans[i]); } return 0; }