求和(NOIP2015)
题目链接:求和
这道题不是很简单,因为数据并不是很小,常规计算会t。
这里引用chenleyu的解答(如果想要cgg原创解答,……改天吧):
这题相对是比较难的,首先我们要解读题目的意思
一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。每个格子上都染了一种颜色color_i用[1,m]当中的一个整数表示),并且写了一个数字number_i。
由这段不难得到,所谓纸带,其实就是一个集合组,每一个小集合(格子)里都有三个元素:编号,颜色和上面写的数
就是这样
纸带[]
|num,col,i|num,col,i|num,col,i||num,col,i||num,col,i||num,col,i|
然后我们再来看那神奇的三元组
“定义一种特殊的三元组:(x,y,z),其中x,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:
1.xyz是整数,x小于y小于z,y-x=z-y
2.colorx=colorz
满足上述条件的三元组的分数规定为(x+z)*(number_x+number_z)”
我们看三元组的第一个条件
首先x小于y小于z这很容易理解,我们来看y-x=z-y
通过等式的性质,我们可以将它进行一些变换
y-x=z-y
y+y=z+x
z+x=2y
这样就可以知道z+x必为偶数,那又因为
奇数+奇数=偶数
偶数+偶数=偶数
奇数+偶数=奇数
所以x和z的奇偶性一定相同
所以题目三元组的条件就可以化为
1 z>x
2 z和x的奇偶性相同
3 z格和x格的颜色相同
(跟y一点关系也没有)
换句话说,只要有两个数奇偶性相同,颜色相同,那他们必是会产生分数的
再来看分数的计算
分数=(x+z)*(num[x]+num[z])
我们再来做一点变换
根据乘法分配律
(x+z)*(num[x]+num[z])
=x*num[x]+x*num[z]+z*num[x]+z*num[z]
那假设i1,i2,i3,i4….的奇偶性相同,颜色相同,那么
他们的得分就为
(i1*num[i1]+i1*num[i2]+i2*num[i1]+i2*num[i3])+(i1*num[i1]+i1*num[i3]+i3*num[i1]+i3*num[i3])+…………..
把括号去掉,把和i1有关的放在一起,把和in有关的放在一起
就成了这样
i1*num[i1]+i1*num[i2]+ i1*num[i1]+i1*num[i3]+…….(和i1有关的)
=i1*(num[i1]+num[i2]+…….+num[in])+n*(i1*num[i1])
于是我们就可以得到这个公式
和in有关的得分就
= in*(num[i1]+num[i2]+…….+num[in])+n*(in*num[in])
再把i1,i2,i3….in的得分加起来就是总分了
因为结果很大所以要记得边做边%10007哦
看得出来,他讲得很详细,我相信你也应该能看懂了,下面看我的代码:
#include<bits/stdc++.h>
#ifdef WIN32 //1
#define LL "%I64d"
#else
#define LL "%lld"
#endif
using namespace std;
int n,c;
int sum[2][100001]={0};
int d[2][100001]={0};
int num[100001];
int col[100001];
long long maxx=0;
int main()
{
scanf("%d%d",&n,&c);
for (int i=1;i<=n;i++){
scanf("%d",&num[i]);
num[i]%=10007;
}
int n1=0,n2=0;
for (int i=1;i<=n;i++){
scanf("%d",&col[i]);
sum[i%2][col[i]]+=num[i]; //2
sum[i%2][col[i]]%=10007;
d[i%2][col[i]]++;
}
for (int i=1;i<=n;i++){
maxx+=1LL*i%10007*((sum[i%2][col[i]]+(d[i%2][col[i]]-2)%10007*num[i]+10007)%10007); //3
maxx%=10007;
}
printf(LL,maxx);
return 0;
}
讲三点(这里是cgg原汁原味的讲解):
1处:这里是cgg曾在信息学培训中,提到过的技巧。
2处:这里是计算每一种颜色单数下标和偶数下标的前缀和。
3处:套公式。
求和(NOIP2015)的更多相关文章
- [NOIP2015普及组]求和
题目 题目描述 一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n.每个格子上都染了一种颜色color_i用[1,m]当中的一个整数表示),并且写了一个数字numberi. 定义一种特殊的三元组: ...
- [P2671][NOIP2015]求和 (数论)
[题目链接] 这位大神讲得很详细:点我 本蒟蒻只会抄抄题解了 #include<bits/stdc++.h> #define max(a,b) (a>b?a:b) #define m ...
- NOIP2015 普及组 洛谷P2671 求和 (数学)
一道数学题...... 采用分组的思想,我们要统计答案的数对满足两个条件:同奇偶,同颜色.所以可以按这两个要求分组. 然后就是分组处理了,对于每组(有k个数),这里面的任意两对数都是满足条件的,可推出 ...
- NOIP2015&2016普及组解题报告
NOIP2015普及组题目下载 NOIP2016普及组题目下载 NOIP2015普及组题目: NOIP2018RP++ NOIP2016普及组题目 NOIP2018RP++ T1 金币\((coin. ...
- 【题解】NOIP2015提高组 复赛
[题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...
- NOIP2015普及组总结
NOIP2015普及组总结 这次考试总体感觉不错,不过觉得时间有点紧,在最后30分钟才打完. 第一题(金币coin):大大的W!爆搜O(N),一分钟打完: 第二题(扫雷游戏mine):同上: 第三题( ...
- 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃
[NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...
- Java程序:从命令行接收多个数字,求和并输出结果
一.设计思想:由于命令行接收的是字符串类型,因此应先将字符串类型转化为整型或其他字符型,然后利用for循环求和并输出结果 二.程序流程图: 三.源程序代码: //王荣荣 2016/9/23 ...
- Java之递归求和的两张方法
方法一: package com.smbea.demo; public class Student { private int sum = 0; /** * 递归求和 * @param num */ ...
随机推荐
- 使用html中的<input>标签上传多个文件(转)
如何使用html上传多个文件呢?我搜索中文怎么也找不到合适的,都是用js动态添加input,然后提交,不能满足我想要的——打开选择文件的窗口后可以一次性选择多个文件. 然后我尝试搜索英文"h ...
- js两个数组对象通过相同元素匹配筛选
let a = [ { name: 'joy', year: '24' }, { name: 'eve', year: '25' } ] let b = [ { name: 'joy', city: ...
- as3.0橡皮擦功能
//主容器 var main:Sprite = new Sprite(); main.mouseEnabled = false; addChild(main) //临时容器(所有操作都将先画在临时容器 ...
- CentOS NFS服务器的搭建与配置
1.查看系统是否已安装NFS [root@bogon ~]# rpm -qa | grep nfs [root@bogon ~]# rpm -qa | grep rpcbind 2.安装NFS [ro ...
- POJ-1458.CommonSubsequence.(DP:最长公共子序列裸题)
本题大意:给出两个字符串,让你求出最长公共子序列的长度并输出. 本题思路:本题是经典的DP问题,由于是两个字符串,那么我们就用一个二维数组来进行区分,用dp[ i ][ j ]来表示在s1和s2中分别 ...
- jQuery之禁止Get请求缓存
如果两次Get请求的URL完全一样,则IE浏览器会调用上次缓存的结果,不会发起新的Http请求. 解决办法:在URL最后面加上时间戳. jQuery全局设置禁止缓存 $.ajaxSetup({ cac ...
- vue 添加子路由,并对路由重定向
// 用户信息首页 { path: '/user/index', name: 'userIndex', component: userIndex, redirect: '/user/index/sho ...
- label 和input/textarea居中对齐
设置label和input/textarea的vertical-align: middle;即可实现垂直方向居中对齐.有时候可能会有偏差,设置input的margin-top使看上去居中对齐
- Xcode 去掉控制台无用打印信息
1. 2.在Environment Variables增加一键值对 OS_ACTIVITY_MODE = disable 转自:https://blog.csdn.net/HelloWorld_198 ...
- Java08-java语法基础(七)构造方法
Java08-java语法基础(七)构造方法 一.构造方法 1.什么是构造方法? 构造方法(类方法)是一个方法名和类名相容的特殊的成员方法. 2.构造方法的作用? 当使用new关键字创建一个对象时,为 ...