P2671 [NOIP2015 普及组] 求和(洛谷前缀和

P2671 [NOIP2015 普及组] 求和

 1 //(x+z)*(num[x]+num[z])=
 2 //(x1+x2)*(y1+y2)+(x1+x3)*(y1+y3)+(x2+x3)*(y2+y3) 
 3 //=x1*(y1*(n-2)+y1+y2+...+yn) 
 4 //+x2*(y2*(n-2)+y1+y2+...+yn)
 5 //+xn*(yn*(n-2)+y1+y2+...+yn)
 6 //即求出y1到yn的前缀和然后循环计算即可 
 7 
 8 //题目要求格子颜色相同,可以把相同颜色的格子分在一个组
 9 //且z-y=y-x,得x+z=2y,所以x和z为同奇或同偶
10 //所以相同格子中又可以奇数分一组偶数分一组
11 //操作时只针对每个组组内操作就行 
12 #include <bits/stdc++.h>
13 using namespace std;
14 const int maxn=1e5+5;
15 //数据范围 
16 const int mol=1e4+7;
17 //模数 
18 int n,m,ans;
19 //m为颜色种数,没啥用 
20 struct node{
21     int id,num,col;
22     //id为下表,没有用
23     //num为格子上的数字
24     //col为格子颜色 
25 }p[maxn];
26 int geshu[maxn][2];
27 //相同颜色格子且下标同奇或同偶格子的个数 
28 int tot[maxn][2];
29 //相同颜色格子且下标同奇或同偶格子的数字和 
30 int main(){
31     scanf("%d%d",&n,&m);
32     for(int i=1;i<=n;i++){
33         scanf("%d",&p[i].num);
34         p[i].id=i;
35     }
36     for(int i=1;i<=n;i++){
37         scanf("%d",&p[i].col);
38         geshu[p[i].col][i%2]++;
39         tot[p[i].col][i%2]=(tot[p[i].col][i%2]+p[i].num)%mol;
40         //时刻模 
41     }
42     for(int i=1;i<=n;i++){
43         ans=(ans+i*((geshu[p[i].col][i%2]-2)*p[i].num%mol+tot[p[i].col][i%2])%mol)%mol;
44         
45     }
46     printf("%d",ans);
47     return 0;
48 }

 

posted @ 2022-09-29 14:50  九州霜  阅读(91)  评论(0编辑  收藏  举报