2017年11月2日提高组T1 Sequence

本文介绍了一种通过差分数组和字符串哈希方法来找出坐标系中与给定直线平行的平滑曲线段的数量。利用前缀哈希技巧,可以在O(n)时间内高效判断两段数字是否满足特定条件。

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 1001
ll 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;
}
在Simulink的Test Sequence模块中对数进行赋值,可以通过以下几种方法实现: ### 使用直接赋值 在Test Sequence编辑器中,可以直接通过信号名称后跟索引的方式对数中的特定元素进行赋值。例如,如果有一个名为`inputArray`的数信号,包含5个元素,则可以使用如下语句对数中的第一个元素进行赋值: ```matlab inputArray(1) = 5; ``` 这种方式适用于需要单独设置每个数元素值的场景[^1]。 ### 使用循环结构批量赋值 当需要为数中的多个元素分配连续或规律性数值时,可以在Test Sequence中使用`for`循环来简化操作。例如: ```matlab var i; for i = 1:5 inputArray(i) = i * 2; end ``` 此代码片段将`inputArray`的所有元素依次赋值为其索引值的两倍。 ### 利用MATLAB Function Block间接赋值 对于更复杂的数初始化需求,可以考虑在Simulink模型中引入MATLAB Function Block,并在其内部编写函数逻辑来生成所需数值。然后,通过Test Sequence调用该函数输出结果给目标信号赋值。例如,在MATLAB Function Block中定义一个函数: ```matlab function out = generateArray() out = [1, 3, 5, 7, 9]; end ``` 随后,在Test Sequence中调用此函数并传递结果至`inputArray`: ```matlab inputArray = generateArray(); ``` ### 利用外部数据源导入 还可以预先准备好数数据文件(如`.mat`文件),并在Test Sequence中加载这些数据以完成数赋值。具体步骤包括先保存数据到工作区或文件,再通过`load`命令读取并在Test Sequence中应用: ```matlab load('arrayData.mat', 'dataArray'); inputArray = dataArray; ``` 这种方法适合处理大量预定义的数据集合作为测试输入的情况。 ### 注意事项 - 在执行任何类型的数赋值之前,请确保已正确声明了相应大小和类型的数变量。 - 如果尝试访问超出当前定义范围之外的数索引位置,可能会导致错误或者未预期的行为。 - 对于多维数的操作,语法上支持类似于`arrayName(dim1, dim2)`的形式来进行指定维度上的元素修改。 以上就是在Simulink Test Sequence中针对数进行赋值的一些常用方法及其示例说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值