抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

本文已经更新完毕,若有错误或需要补充的内容请在评论区留言。

一道找规律与推导的题目。

题目

Portal.

展开题目

一条狭长的纸带被均匀划分出了nn个格子,格子编号从11nn。每个格子上都染了一种颜色coloricolor_i[1,m][1,m]当中的一个整数表示),并且写了一个数字numberinumber_i

定义一种特殊的三元组:(x,y,z)(x,y,z),其中x,y,zx,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:

  1. xyzxyz是整数,x<y<z,yx=zyx<y<z,y-x=z-y

  2. colorx=colorzcolorx=colorz

满足上述条件的三元组的分数规定为(x+z)×(numberx+numberz)(x+z) \times (number_x+number_z)。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以10,00710,007所得的余数即可。

输入格式

第一行是用一个空格隔开的两个正整数nnm,nm,n表纸带上格子的个数,mm表纸带上颜色的种类数。

第二行有nn用空格隔开的正整数,第ii数字numbernumber表纸带上编号为ii格子上面写的数字。

第三行有nn用空格隔开的正整数,第ii数字colorcolor表纸带上编号为ii格子染的颜色。

输出格式

一个整数,表示所求的纸带分数除以1000710007所得的余数。

样例输入#1
6 25 5 3 2 2 22 2 1 1 2 1
样例输出#1
82
样例输入#2
15 45 10 8 2 2 2 9 9 7 7 5 6 4 2 42 2 3 3 4 3 3 2 4 4 4 4 1 1 1
样例输出#2
1388

【输入输出样例 1 说明】

纸带如题目描述中的图所示。

所有满足条件的三元组为: (1,3,5),(4,5,6)(1, 3, 5), (4, 5, 6)

所以纸带的分数为(1+5)×(5+2)+(4+6)×(2+2)=42+40=82(1 + 5) \times (5 + 2) + (4 + 6) \times (2 + 2) = 42 + 40 = 82

对于第 11 组至第 22 组数据, 1n100,1m51 \le n \le 100, 1 \le m \le 5

对于第 33 组至第 44 组数据, 1n3000,1m1001 \le n \le 3000, 1 \le m \le 100

对于第 55 组至第 66 组数据, 1n100000,1m1000001 \le n \le 100000, 1 \le m \le 100000,且不存在出现次数超过 2020 的颜色;

对于全部 1010 组数据 , 1n100000,1m100000,1colorim,1numberi1000001 \le n \le 100000, 1 \le m \le 100000, 1 \le color_i \le m,1\le number_i\le 100000

解答

x<y<z,yx=zyx<y<z,y-x=z-y 表示的显然是距离相等,也就是 yyx,zx,z 的平均数,而且 yy 是个整数,所以 x,zx,z 奇偶性相同,分别进行计算即可。

又因为颜色与答案无关,所以颜色也可以分别计算。现在的问题就转化为了求:

i=1nj=i+1n(Ai+Aj)(Bi+Bj)\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}(A_i+A_j)(B_i+B_j)

展开后会发现当中有 n1n-1AiBiA_i B_i,和所有 A,BA,B 相乘。利用多项式乘法的特性,可得原式等于:

i=1nAi×i=1nBi+i=1n(n2)AiBi\sum\limits_{i=1}^{n}A_i \times \sum\limits_{i=1}^{n}B_i + \sum\limits_{i=1}^{n}(n-2)A_iB_i

代码就很简单了:

查看代码
#include <iostream>
#include <cstdio>
#include <vector>

#define pii pair<int, int>
#define X first
#define Y second

using namespace std;

const int MOD = 10007;

int n, m;
int number[100005], color[100005];
vector <pii> v[100005][2];

int main(void)
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) scanf("%d", number + i), number[i] %= MOD;
    for (int i = 1; i <= n; ++i) scanf("%d", color + i);
    for (int i = 1; i <= n; ++i)
        v[color[i]][i & 1].push_back(make_pair(i, number[i]));
    int ans = 0;
    for (int op = 0; op < 2; ++op)
    {
        for (int i = 1; i <= m; ++i)
        {
            int R = v[i][op].size();
            if (R >= 2)
            {
                int res = 0, ret = 0;
                for (int j = 0; j < R; ++j)
                    res = (res + v[i][op][j].X) % MOD, ret = (ret + v[i][op][j].Y) % MOD;
                ans = (ans + res * ret % MOD) % MOD;
                for (int j = 0; j < R; ++j)
                    ans = (ans + (R - 2) % MOD * v[i][op][j].X % MOD * v[i][op][j].Y % MOD) % MOD;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

评论

若无法加载,请尝试刷新,欢迎讨论、交流和提出意见,支持 Markdown 与 LaTeX 语法(公式与文字间必须有空格)!