Codefroces 213E. Two Permutations

E. Two Permutations
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

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.

Output

On a single line print the answer to the problem.

Examples
Input
1 1
1
1
Output
1
Input
1 2
1
2 1
Output
2
Input
3 3
2 3 1
1 2 3
Output
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 }
Codeforces213E

 

posted @ 2017-10-15 15:34  嘒彼小星  阅读(253)  评论(0编辑  收藏  举报