2017年11月2日提高组T1 Sequence

来源:互联网 发布:珠宝标签打印软件 编辑:程序博客网 时间:2024/05/03 01:56

Description


这里写图片描述

Input


这里写图片描述

Output


这里写图片描述

Hint


这里写图片描述

Solution


想像一下,把点在坐标系里面描出来就能发现实际上是要找出多少段连续m个点描出的平滑曲线与b平行(意会一下)。一个简单的方法是做一个差分数组,kmp判断有多少字串。差分数组相同保证了相邻两点的斜率相同(口胡)

这里写了不太熟悉的字符串哈希做法。钦定这是一个1e9进制数,做一个前缀哈希。若两段数字的每一位同时相差固定的数字,那他们的差一定形如xxxxxxxxx,即一个m位的全为x的数字。预处理一下然后O(n)判断就可以了。如果担心怕被卡掉可以多%几个大素数

Code


#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include <queue>#include <vector>#include <algorithm>#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)#define erg(i, st) for (int i = ls[st]; i; i = e[i].next)#define fill(x, t) memset(x, t, sizeof(x))#define min(x, y) ((x)<(y)?(x):(y))#define max(x, y) ((x)>(y)?(x):(y))#define ld long double#define db double#define ll long long#define MOD1 403219#define MOD2 1000000007#define INF 0x3f3f3f3f#define N 2022001#define E 1001#define L 1001ll a[N], b[N], h1[N], h2[N], v1, v2, cf1[N], cf2[N];ll base1 = 1000000000 % MOD1;ll base2 = 1000000000 % MOD2;inline int read() {    int x = 0, v = 1;    char ch = getchar();    for (; ch < '0' || ch > '9'; v *= (ch == '-')?(-1):(1), ch = getchar());    for (; ch <= '9' && ch >= '0'; (x *= 10) += ch - '0', ch = getchar());    return x * v;}int main(void) {    int n = read();    int m = read();    cf1[0] = cf2[0] = 1;    rep(i, 1, n) {        a[i] = read();        h1[i] = (h1[i - 1] * base1 + a[i]) % MOD1;        h2[i] = (h2[i - 1] * base2 + a[i]) % MOD2;        cf1[i] = cf1[i - 1] * base1 % MOD1;        cf2[i] = cf2[i - 1] * base2 % MOD2;    }    int rec1 = 0, rec2 = 0;    rep(i, 1, m) {        v1 = (v1 * base1 + 1) % MOD1;        v2 = (v2 * base2 + 1) % MOD2;        b[i] = read();        rec1 = (rec1 * base1 + b[i]) % MOD1;        rec2 = (rec2 * base2 + b[i]) % MOD2;    }    int ans = 0;    rep(r, m, n) {        int l = r - m + 1;        int now1 = (h1[r] + MOD1 - (h1[l - 1] * cf1[m]) % MOD1) % MOD1;        int now2 = (h2[r] + MOD2 - (h2[l - 1] * cf2[m]) % MOD2) % MOD2;        int c = abs(a[l] - b[1]);        if ((now1 - rec1 + MOD1) % MOD1 == v1 * c % MOD1 && (now2 - rec2 + MOD2) % MOD2 == v2 * c % MOD2) {            ans += 1;        }    }    printf("%d\n", ans);    return 0;}
原创粉丝点击