P2671 [NOIP2015 普及组] 求和
题解
定义一种特殊的三元组:(x,y,z),其中x,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:
- x y z是整数,x<y<z,y-x=z-y
- colorx = colorz
通过第一个条件易得x,y一定是同奇同偶
第二个条件无非是在限制这个三元组中x,z颜色相同
(u1s1,这个玩意跟y貌似没什么关系,所以是二元组
满足上述条件的三元组的分数规定为(x+z)*(number_x+number_z)
题目的最终目标是计算所有三元组分数和
根据分数规定,纯模拟,直接TLE
细想其实这个三元组跟y没关系,所以只用考虑x,z
那么可以考虑把同奇同偶且颜色相同的分为一组
如果此时再直接进行模拟,也还是会TLE
那么想想办法优化?
(x+z) * (number_x+number_z)=x * number_x+x *number_y+y * number_x+y * number_y
所以同一组内的分数
设m为组内的个数
组内第一个数所得得部分分数即
x * number_x+x *number_y
=
i
∗
∑
i
=
2
m
n
u
m
[
i
]
+
(
n
−
1
)
∗
(
i
∗
n
u
m
[
i
]
)
i*\sum_{i=2}^mnum[i]+(n-1)*(i*num[i])
i∗∑i=2mnum[i]+(n−1)∗(i∗num[i])
=
i
∗
∑
i
=
1
m
n
u
m
[
i
]
+
(
n
−
2
)
∗
(
i
∗
n
u
m
[
i
]
)
i*\sum_{i=1}^mnum[i]+(n-2)*(i*num[i])
i∗∑i=1mnum[i]+(n−2)∗(i∗num[i])
那么一个组的得分数
=
∑
i
=
1
m
(
i
∗
∑
j
=
1
m
∗
n
u
m
[
j
]
+
(
m
−
2
)
∗
n
u
m
[
i
]
)
\sum_{i=1}^m(i*\sum_{j=1}^m*num[j]+(m-2)*num[i])
∑i=1m(i∗∑j=1m∗num[j]+(m−2)∗num[i])
∑
j
=
1
m
∗
n
u
m
[
j
]
\sum_{j=1}^m*num[j]
∑j=1m∗num[j]这一部分可以再分组时用前缀和优化
时间复杂度即可达到O(n)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e5+10;
int n,m;
int num[maxn];
long long sum[maxn][3];
int t[maxn][3];
const int mod=10007;
int c[maxn];
int main(){
cin>>n>>m;memset(t,0,sizeof(t));
for(int i=1;i<=n;++i) cin>>num[i];
for(int i=1;i<=n;++i){
cin>>c[i];
t[c[i]][i%2]++;//记录组内个数
sum[c[i]][i%2]=(sum[c[i]][i%2]+num[i])%mod;
}long long ans=0;
for(int i=1;i<=n;++i){
ans=(ans+i*(sum[c[i]][i%2]+(t[c[i]][i%2]-2)*num[i]))%mod;
}cout<<ans<<endl;
return 0;
}