Rubik is very keen on number permutations.
A permutation a with length n is a sequence, consisting of n different numbers from 1 to n. Element number i (1 ≤ i ≤ n) of this permutation will be denoted as ai.
Furik decided to make a present to Rubik and came up with a new problem on permutations. Furik tells Rubik two number permutations: permutation a with length n and permutation b with length m. Rubik must give an answer to the problem: how many distinct integers d exist, such that sequence c (c1 = a1 + d, c2 = a2 + d, ..., cn = an + d) of length n is a subsequence of b.
Sequence a is a subsequence of sequence b, if there are such indices i1, i2, ..., in (1 ≤ i1 < i2 < ... < in ≤ m), that a1 = bi1, a2 = bi2, ..., an = bin, where n is the length of sequence a, and m is the length of sequence b.
You are given permutations a and b, help Rubik solve the given problem.
The first line contains two integers n and m (1 ≤ n ≤ m ≤ 200000) — the sizes of the given permutations. The second line contains n distinct integers — permutation a, the third line contains m distinct integers — permutation b. Numbers on the lines are separated by spaces.
On a single line print the answer to the problem.
1 1
1
1
1
1 2
1
2 1
2
3 3
2 3 1
1 2 3
0
【题解】
由于a和b都是排列,其实就是找b中i...i + n - 1的相对位置与a中1...n的相对位置是否相同
康托展开显然是不好做的(反正我不会)
于是我们可以hash,拿线段树做即可
线段树下标是排列位置,线段数内的值是该位置的值
先把1...n的位置放进去,然后查行不行
然后把1拿出来,把n + 1的位置放进去,看看行不行
(注意由于每个数字都增加1,因此hash值应增加B^0 + B^1 + B^2.. + B^n,前缀和处理即可)
以此类推
因为没有膜够所以WA了好几发
具体看代码
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #define max(a, b) ((a) > (b) ? (a) : (b)) 6 #define min(a, b) ((a) < (b) ? (a) : (b)) 7 inline void swap(long long &a, long long &b) 8 { 9 long long tmp = a;a = b;b = tmp; 10 } 11 inline void read(long long &x) 12 { 13 x = 0;char ch = getchar(), c = ch; 14 while(ch < '0' || ch > '9')c = ch, ch = getchar(); 15 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 16 if(c == '-')x = -x; 17 } 18 19 const long long MAXN = 1000000 + 10; 20 const long long MOD1 = 19260817; 21 const long long MOD2 = 1000000007; 22 const long long B = 232; 23 const long long MOD = 1000000007; 24 25 long long data[2][MAXN], ans, sum1, sum2, sum[MAXN], val1, val2, bit1[MAXN], bit2[MAXN], cnt[MAXN << 1], size1[MAXN], size2[MAXN], n, m; 26 27 //在权值p这个位置,[x == 1]增加k,[x == -1]减小k 28 void modify(long long p, long long k, long long x, long long o = 1, long long l = 1, long long r = m) 29 { 30 if(l == r && p == l) 31 { 32 data[0][o] += k * x % MOD1; 33 data[1][o] += k * x % MOD2; 34 size1[o] += x, size2[o] += x; 35 return; 36 } 37 long long mid = (l + r) >> 1; 38 if(mid >= p) modify(p, k, x, o << 1, l, mid); 39 else modify(p, k, x, o << 1 | 1, mid + 1, r); 40 data[0][o] = ((data[0][o << 1 | 1] * bit1[size1[o << 1]]) % MOD1 + data[0][o << 1]) % MOD1; 41 data[1][o] = ((data[1][o << 1 | 1] * bit2[size2[o << 1]]) % MOD2 + data[1][o << 1]) % MOD2; 42 size1[o] = size1[o << 1] + size1[o << 1 | 1]; 43 size2[o] = size2[o << 1] + size2[o << 1 | 1]; 44 return; 45 } 46 47 int main() 48 { 49 // freopen("data.txt", "r", stdin); 50 read(n) ,read(m); 51 bit1[0] = 1;bit2[0] = 1; 52 for(register long long i = 1;i <= m;++ i) 53 bit1[i] = (bit1[i - 1] * B)%MOD1, bit2[i] = (bit2[i - 1] * B)%MOD2; 54 for(register long long i = 1;i <= n;++ i) 55 { 56 long long tmp; 57 read(tmp); 58 val1 += tmp * bit1[i - 1] % MOD1; 59 val1 %= MOD1; 60 val2 += tmp * bit2[i - 1] % MOD2; 61 val2 %= MOD2; 62 sum1 += bit1[i - 1];sum1 %= MOD1; 63 sum2 += bit2[i - 1];sum2 %= MOD2; 64 } 65 for(register long long i = 1;i <= m;++ i) 66 { 67 long long tmp; 68 read(tmp); 69 cnt[tmp] = i; 70 } 71 for(register long long i = 1;i <= m;++ i) 72 { 73 modify(cnt[i], i, 1); 74 if(i >= n) 75 { 76 if(data[1][1] == (val2 + (sum2 * (i - n))%MOD2)%MOD2 && data[0][1] == (val1 + (sum1 * (i - n))%MOD1)%MOD1) 77 ++ ans; 78 modify(cnt[i - n + 1], i - n + 1, -1); 79 } 80 } 81 printf("%d", ans); 82 return 0; 83 }