[Noip2015PJ] 求和
Description
一条狭长的纸带被均匀划分出了 \(n\) 个格子,格子编号从 \(1\) 到 \(n\) 。每个格子上都染了一种颜色 \(color_i\) 用 \([1,m]\) 当中的一个整数表示),并且写了一个数字 \(number_i\) 。
定义一种特殊的三元组:\((x,y,z)\),其中 \(x,y,z\) 都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:
- \(x,y,z\) 是整数, \(x<y<z\),\(y-x=z-y\)
- \(color_x=color_z\)
满足上述条件的三元组的分数规定为 \((x+z)\times (number_x+number_z)\)。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以 \(10,007\) 所得的余数即可。
Input
第一行是用一个空格隔开的两个正整数 \(n\) 和 \(m\) , \(n\) 表纸带上格子的个数, \(m\) 表纸带上颜色的种类数。
第二行有 \(n\) 用空格隔开的正整数,第 \(i\) 数字 \(number\) 表纸带上编号为 \(i\) 格子上面写的数字。
第三行有 \(n\) 用空格隔开的正整数,第 \(i\) 数字 \(color\) 表纸带上编号为 \(i\) 格子染的颜色。
Output
共一行,一个整数,表示所求的纸带分数除以 \(10,007\) 所得的余数。
Hint
对 于 全 部 \(10\) 组 数 据 , \(1\leq n\leq 100000, 1\leq m\leq 100000, 1\leq color_i\leq m,1\leq number_i\leq 100000\)
Solution
首先能够推导出 \(x\) 和 \(z\) 的编号一定是奇偶性相同的。
所以想到对于奇数点和偶数点分开统计答案。
拆一下 \((x,y,z)\) 三元组对答案产生的贡献:\((x+z)\times (number_x+number_z)=x\times number_x+x\times number_z+z\times number_x+z\times number_z\)
观察拆完的式子,发现后边三项中与 \(x\) 无关的项都能用前缀和维护。
比如说第二项中的 \(x\times number_z,number_z\) 显然能用前缀和统计。即扫描到 \(x\) 节点时它和后面某个点 \(z\) 对答案在第二项的贡献即为 \((qzh\_number[z]-qzh\_number[x])\times x\)。
所以得到了以下这个基本完成的算法:
对于每个颜色,分别开两个数组,存储奇数节点和偶数节点的编号,记为 \(odd\) 和 \(even\)。
对于每个颜色中的 \(even\) 和 \(odd\),再开三个前缀和数组分别维护 \(number_z,z,z\times number_z\) 的和。
然后扫描每个颜色,对每个颜色中存储的每个编号从头到尾扫一遍,答案加上这个点之后的所有点与这个点组成的三元组的贡献即可。
Code
#include<cstdio>
#include<vector>
#include<cctype>
#define N 100005
#define mod 10007
#define int long long
int ans;
int n,m;
int num[N];
int col[N];
bool vis[N];
std::vector<int> even[N],odd[N];
std::vector<int> qzh1[N],qzh2[N],qzh3[N];
std::vector<int> qzh4[N],qzh5[N],qzh6[N];
inline char nc(){
static const int BS=1<<22;
static unsigned char buf[BS],*st,*ed;
if(st==ed) ed=buf+fread(st=buf,1,BS,stdin);
return st==ed?EOF:*st++;
}
//#define nc getchar
inline int getint(){
char ch;
int res=0;
while(!isdigit(ch=nc()));
while(isdigit(ch)){
res=(res<<1)+(res<<3)+(ch^48);
ch=nc();
}
return res;
}
signed main(){
n=getint(),m=getint();
for(int i=1;i<=n;i++)
num[i]=getint();
for(int i=1;i<=n;i++){
col[i]=getint();
if(i&1){
odd[col[i]].push_back(i);
int a=qzh1[col[i]].size();
if(!qzh1[col[i]].empty())
qzh1[col[i]].push_back((qzh1[col[i]][a-1]+num[i]));
else qzh1[col[i]].push_back(num[i]);
a=qzh2[col[i]].size();
if(!qzh2[col[i]].empty())
qzh2[col[i]].push_back((qzh2[col[i]][a-1]+i));
else qzh2[col[i]].push_back(i);
a=qzh3[col[i]].size();
if(!qzh3[col[i]].empty())
qzh3[col[i]].push_back((qzh3[col[i]][a-1]+i*num[i]));
else qzh3[col[i]].push_back((i*num[i]));
}
else{
even[col[i]].push_back(i);
if(!qzh4[col[i]].empty())
qzh4[col[i]].push_back((qzh4[col[i]][qzh4[col[i]].size()-1]+num[i]));
else qzh4[col[i]].push_back(num[i]);
if(!qzh5[col[i]].empty())
qzh5[col[i]].push_back((qzh5[col[i]][qzh5[col[i]].size()-1]+i));
else qzh5[col[i]].push_back(i);
if(!qzh6[col[i]].empty())
qzh6[col[i]].push_back((qzh6[col[i]][qzh6[col[i]].size()-1]+i*num[i]));
else qzh6[col[i]].push_back((i*num[i]));
}
}
for(int k=1;k<=n;k++){
if(vis[col[k]]) continue;
vis[col[k]]=1;
for(int i=0;i<odd[col[k]].size();i++){
int p=odd[col[k]].size()-i-1;
(ans+=odd[col[k]][i]%mod*num[odd[col[k]][i]]%mod*p%mod)%=mod;
(ans+=odd[col[k]][i]%mod*(qzh1[col[k]][qzh1[col[k]].size()-1]-qzh1[col[k]][i])%mod)%=mod;
(ans+=num[odd[col[k]][i]]%mod*(qzh2[col[k]][qzh2[col[k]].size()-1]-qzh2[col[k]][i])%mod)%=mod;
(ans+=qzh3[col[k]][qzh3[col[k]].size()-1]-qzh3[col[k]][i])%=mod;
}
for(int i=0;i<even[col[k]].size();i++){
int p=even[col[k]].size()-i-1;
(ans+=even[col[k]][i]%mod*num[even[col[k]][i]]%mod*p%mod)%=mod;
(ans+=even[col[k]][i]%mod*(qzh4[col[k]][qzh4[col[k]].size()-1]-qzh4[col[k]][i])%mod)%=mod;
(ans+=num[even[col[k]][i]]%mod*(qzh5[col[k]][qzh5[col[k]].size()-1]-qzh5[col[k]][i])%mod)%=mod;
(ans+=qzh6[col[k]][qzh6[col[k]].size()-1]-qzh6[col[k]][i])%=mod;
}
}
printf("%lld\n",ans%mod);
return 0;
}
[Noip2015PJ] 求和的更多相关文章
- NOIP2015pj求和
题目描述 一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n.每个格子上都染了一种颜色color_i用[1,m]当中的一个整数表示),并且写了一个数字number_i. 定义一种特殊的三元组:(x ...
- Java程序:从命令行接收多个数字,求和并输出结果
一.设计思想:由于命令行接收的是字符串类型,因此应先将字符串类型转化为整型或其他字符型,然后利用for循环求和并输出结果 二.程序流程图: 三.源程序代码: //王荣荣 2016/9/23 ...
- Java之递归求和的两张方法
方法一: package com.smbea.demo; public class Student { private int sum = 0; /** * 递归求和 * @param num */ ...
- EXCEL中对1个单元格中多个数字求和
如A1=3779.3759.3769.3781.3750,A2对A1中4个数字求和怎么求!请高手赐教! 方法一:在B1中输入公式=SUM(MID(A1,{1,6,11,16,21},4)*1) 方法二 ...
- codevs 1082 线段树区间求和
codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...
- 从sum()求和引发的思考
sum()求和是一个非常简单的函数,以前我的写法是这样,我想大部分和我一样刚开始学习JS的同学写出来的也会是这样. function sum() { var total=null; for(var i ...
- //给定N个整数序列{A1,A2,A3...An},求函数f(i,j)=(k=i~j)Ak的求和
//给定N个整数序列{A1,A2,A3...An},求函数f(i,j)=(k=i~j)Ak的求和 # include<stdio.h> void main() { ,sum1; ]={,- ...
- Ajax中get请求和post请求
我们在使用Ajax向服务器发送数据时,可以采用Get方式请求服务器,也可以使用Post方式请求服务器,那么什么时候该采用Get方式,什么时候该采用Post方式呢? Get请求和Post请求的区别: 1 ...
- POJ 2823 Sliding Window 线段树区间求和问题
题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...
随机推荐
- STL基础4:deque
#include <iostream> #include <queue> #include <string> using namespace std; #defin ...
- String 常用函数
判断字符串是否包含指定字符str.contains("string"); 查找指定字符索引str.indexOf("s"'); 查找最后出现的字符索引str.i ...
- sqoop加载mysql数据库
./bin/sqoop list-databases --connect jdbc:mysql://node-001:3306/ --username root --password hadoop
- The Python Challenge 0-4
The Python Challenge 0-4 项目地址:http://www.pythonchallenge.com/ Level-0 提示Hint: try to change the URL ...
- 完整的SOPC开发流程体验
课程目标:学习并掌握完整的SOPC开发流程. 开发环境:Quartus15.1 学习内容:1.使用QSYS工具建立能够运行流水灯项目的NIOS II处理器系统 2.在quartus ii中添加NIOS ...
- 《mysql必知必会》学习_第17章_20180807_欢
第17章:组合查询 P114 select vend_id ,prod_id,prod_price from products where prod_price <=5 ; select ven ...
- day_1 Python介绍及计算机组成和系统
python学习路线 基础语法 - 文件操作 - 函数 - 模块 - 面向对象(类) - 网络编程 - 数据库 - 前段 - 项目 学习方法 wwwh: what-why-where-how #wha ...
- Dynamic Programming | Set 3 (Longest Increasing Subsequence)
在 Dynamic Programming | Set 1 (Overlapping Subproblems Property) 和 Dynamic Programming | Set 2 (Opti ...
- WPF 开机注册自启动及设置确保以管理员运行
最近用到开机自启动设置,在此记录下设置自启动的步骤,如果对各位有需要可以借阅,之前设置管理权限解释在创建解决方案是将VS以管理员方式打开,这种方法可以实现,但是个人还是偏向与本文的方式,不多说啥了,下 ...
- postgres Date/Time 学习笔记
一.Date/Time Types 参考文档:https://www.postgresql.org/docs/9.2/static/datatype-datetime.html Types 别名 ti ...