histcat

histcat

P2671 [NOIP2015 普及组] 和を求める

問題#

[NOIP2015 普及组] 和を求める#

問題背景#

NOIP2015 普及组 T3

問題の説明#

細長い紙テープが均等に $n$ 個のマスに分けられ、マスの番号は $1$ から $n$ までです。各マスには色 $color_i$($[1,m]$ の中の整数で表される)が染められ、数字 $number_i$ が書かれています。

image

特別な三つ組 $(x,y,z)$ を定義します。ここで $x,y,z$ は紙テープ上のマスの番号を表し、この三つ組は以下の二つの条件を満たす必要があります:

  1. $xyz$ は整数であり、$x<y<z,y-x=z-y$ であること
  2. $colorx=colorz$ であること

上記の条件を満たす三つ組のスコアは $(x+z) \times (number_x+number_z)$ と定義されます。全体の紙テープのスコアは、条件を満たすすべての三つ組のスコアの合計です。このスコアは非常に大きくなる可能性があるため、全体の紙テープのスコアを $10,007$ で割った余りを出力してください。

($n, m <= 100000$)

解答#

まず、結果が y に全く関係ないことが一目でわかります。y が唯一制限するのは x であり、z の奇偶性は同じでなければなりません。

したがって、答えに入るマスの間は同じ奇偶性かつ同じ色である必要があります。同じ奇偶性と色を持つマスをグループに分けます。

その中の一つのグループを考え、差分法を考慮します。新しい数が追加されると、答えにどれだけの貢献をするかを見てみましょう。

表を描くと、次のようにわかります。

number\ 番号1234
n_111
n_211
n_311
n_41111+1+1

例えば、このグループの 4 番目を追加すると、次のような貢献が生まれます。
その後、前方和を統計し、計算できます。

コード#

#include<bits/stdc++.h>
#define int long long
using namespace std;

int n, m;

const int N = 100100;
const int mod = 10007;

int counta[N][2], sum_n[N][2], sum_f[N][2], sum_fn[N][2];//count i,j は色がi、番号がjの数量を表し、sum i,j は色がi、番号がjの 
int a[N], b[N];

int read()
{
	int f = 1, x = 0;
	char ch = getchar();
	while(ch < '0' || ch > '9')
	{
		if(ch == '-') f = -1;
		ch = getchar();
	}

	while(ch >= '0' && ch <= '9')
	{
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return f * x;
}

signed main()
{
	n = read(), m = read();
	long long ans = 0;
	for(int i = 1;i <= n;i++)
	{
		a[i] = read();//数字——n 
	}

	for(int i = 1;i <= n;i++)
	{
		b[i] = read();//色——b 
	}

	for(int i = 1;i <= n;i++)
	{
		ans = (ans + sum_fn[b[i]][i % 2]) % mod;
		counta[b[i]][i % 2] ++;
		sum_f[b[i]][i % 2] = (sum_f[b[i]][i % 2] + i) % mod;
		sum_n[b[i]][i % 2] = (sum_n[b[i]][i % 2] + a[i]) % mod;
		sum_fn[b[i]][i % 2] = (sum_fn[b[i]][i % 2] + (i * a[i]) % mod) % mod;
		ans = (ans + (i * sum_n[b[i]][i % 2]) % mod) % mod;
		ans = (ans + (a[i] * sum_f[b[i]][i % 2]) % mod) % mod;
		ans = (ans + ((  (counta[b[i]][i % 2] - 3) * i * a[i]) % mod + mod ) % mod) % mod;
	}
	printf("%lld", ((ans % mod) + mod) % mod);
	return 0;
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。