关键是没想到按大小顺序把第二个排列一个一个加入线段树, 然后线段树维护整体的hash值,
得到的hs值减去一个sub 之后与, 第一个排列的hash值比较。
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} int n, m; int a[N], b[N]; int pos[N]; ull Pow[N]; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 struct info { int cnt; ull hs; }; info operator + (const info& a, const info& b) { info c; c.cnt = a.cnt + b.cnt; c.hs = b.hs + a.hs * Pow[b.cnt]; return c; } struct segmentTree { info a[N << 2]; void update(int p, int v, int l, int r, int rt) { if(l == r) { if(!v) a[rt].cnt = a[rt].hs = 0; else a[rt].cnt = 1, a[rt].hs = v; return; } int mid = l + r >> 1; if(p <= mid) update(p, v, lson); else update(p, v, rson); a[rt] = a[rt << 1] + a[rt << 1 | 1]; } } Tree; int main() { for(int i = Pow[0] = 1; i < N; i++) Pow[i] = Pow[i - 1] * 233333; scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= m; i++) { scanf("%d", &b[i]); pos[b[i]] = i; } int ans = 0; ull hsA = 0; ull sub = 0; for(int i = 1; i <= n; i++) hsA *= 233333, hsA += a[i]; for(int i = 1; i <= n; i++) sub *= 233333, sub += 1; for(int i = 1; i <= n; i++) Tree.update(pos[i], i, 1, m, 1); ans += hsA == Tree.a[1].hs; for(int i = n + 1; i <= m; i++) { Tree.update(pos[i - n], 0, 1, m, 1); Tree.update(pos[i], i, 1, m, 1); ull hsB = Tree.a[1].hs; hsB -= sub * (i - n); ans += hsA == hsB; } printf("%d ", ans); return 0; } /* */