P2671 求和【前缀和】

题目描述

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

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

xyzxyzxyz是整数,x<y<z,y−x=z−yx<y<z,y-x=z-yx<y<z,y−x=z−y

colorx=colorzcolorx=colorzcolorx=colorz

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

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

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

第三行有nnn用空格隔开的正整数,第iii数字colorcolorcolor表纸带上编号为iii格子染的颜色。
输出格式

一个整数,表示所求的纸带分数除以100071000710007所得的余数。
输入输出样例
输入 #1

6 2
5 5 3 2 2 2
2 2 1 1 2 1

输出 #1

82

输入 #2

15 4
5 10 8 2 2 2 9 9 7 7 5 6 4 2 4
2 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,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(1+5)×(5+2)+(4+6)×(2+2)=42+40=82。

对于第 111 组至第 222 组数据, 1≤n≤100,1≤m≤51 ≤ n ≤ 100, 1 ≤ m ≤ 51≤n≤100,1≤m≤5;

对于第3 33 组至第 444 组数据, 1≤n≤3000,1≤m≤1001 ≤ n ≤ 3000, 1 ≤ m ≤ 1001≤n≤3000,1≤m≤100;

对于第 555 组至第6 6 6组数据, 1≤n≤100000,1≤m≤1000001 ≤ n ≤ 100000, 1 ≤ m ≤ 1000001≤n≤100000,1≤m≤100000,且不存在出现次数超过20 20 20的颜色;

对 于 全 部 101010 组 数 据 , 1≤n≤100000,1≤m≤100000,1≤color_i≤m,1≤number_i≤1000001 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, 1 ≤ color_i ≤ m,1≤number_i≤1000001≤n≤100000,1≤m≤100000,1≤color_i≤m,1≤number_i≤100000

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;
const int mod = 10007;
int tot[maxn][2], id[maxn][2];
int sum[maxn][2];
int store[maxn][2];
int col[maxn], a[maxn];
int n, m;

int main() {
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
		cin >> a[i];
	for(int i = 1; i <= n; i++) {
		cin >> col[i];
		int t2 = i % 2;
		id[col[i]][t2]++;
		sum[col[i]][t2] += a[i] % mod;
		sum[col[i]][t2] %= mod;
	}
	ll ans = 0;
	for(int i = 1; i <= n ;i++) {
		ans += 1ll * sum[col[i]][i % 2]* i % mod + 1ll * i * a[i] * (id[col[i]][i % 2] - 2) % mod;
		ans %= mod; 
	}
	cout << ans << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值