题目链接:求和

这道题不是很简单,因为数据并不是很小,常规计算会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)的更多相关文章

  1. [NOIP2015普及组]求和

    题目 题目描述 一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n.每个格子上都染了一种颜色color_i用[1,m]当中的一个整数表示),并且写了一个数字numberi. 定义一种特殊的三元组: ...

  2. [P2671][NOIP2015]求和 (数论)

    [题目链接] 这位大神讲得很详细:点我 本蒟蒻只会抄抄题解了 #include<bits/stdc++.h> #define max(a,b) (a>b?a:b) #define m ...

  3. NOIP2015 普及组 洛谷P2671 求和 (数学)

    一道数学题...... 采用分组的思想,我们要统计答案的数对满足两个条件:同奇偶,同颜色.所以可以按这两个要求分组. 然后就是分组处理了,对于每组(有k个数),这里面的任意两对数都是满足条件的,可推出 ...

  4. NOIP2015&2016普及组解题报告

    NOIP2015普及组题目下载 NOIP2016普及组题目下载 NOIP2015普及组题目: NOIP2018RP++ NOIP2016普及组题目 NOIP2018RP++ T1 金币\((coin. ...

  5. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  6. NOIP2015普及组总结

    NOIP2015普及组总结 这次考试总体感觉不错,不过觉得时间有点紧,在最后30分钟才打完. 第一题(金币coin):大大的W!爆搜O(N),一分钟打完: 第二题(扫雷游戏mine):同上: 第三题( ...

  7. 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃

    [NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...

  8. Java程序:从命令行接收多个数字,求和并输出结果

    一.设计思想:由于命令行接收的是字符串类型,因此应先将字符串类型转化为整型或其他字符型,然后利用for循环求和并输出结果 二.程序流程图: 三.源程序代码:   //王荣荣 2016/9/23     ...

  9. Java之递归求和的两张方法

    方法一: package com.smbea.demo; public class Student { private int sum = 0; /** * 递归求和 * @param num */ ...

随机推荐

  1. SoundChannel和soundTransform的关系

    SoundChannel 音乐的  播放  暂停  当前获取当前位置  长度 leftPeak : Number[只读] 左声道的当前幅度(音量),范围从 0(静音)至 1(最大幅度) rightPe ...

  2. oracle中job定时任务96

    .INTERVAL参数常用值示例 每天午夜12点            ''TRUNC(SYSDATE + 1)'' 每天早上8点30分         ''TRUNC(SYSDATE + 1) +  ...

  3. composer windows安装,使用新手入门

    一.前期准备: 1.下载安装包,https://getcomposer.org/download/ 2.在php.ini文档中打开extension=php_openssl.dll 3.下载php_s ...

  4. 基于java NIO 的服务端与客户端代码

    在对java NIO  selector 与 Buffer Channel  有一定的了解之后,我们进行编写java nio 实现的 客户端与服务端例子: 服务端: public class NIOC ...

  5. Activity横竖屏切换时 一些数据的保存

    private VideoView videoView; 02.private static final String VIDEO_PATH = Environment 03. .getExterna ...

  6. pthreads v3下一些坑和需要注意的地方

    一.子线程无法访问父线程的全局变量,但父线程可以访问子线程的变量 <?php class Task extends Thread { public $data; public function ...

  7. go语言中的函数

    package main; import "fmt" func main() { a, b, c := A(1, 2, 3); fmt.Println(a, b, c); //调用 ...

  8. std::move 移动对象资源

    场景: C++ 标准库使用比如vector::push_back 等这类函数时,会对参数的对象进行复制,连数据也会复制.这就会造成对象内存的额外创建, 本来原意是想把参数push_back进去就行了. ...

  9. RNA测序相对基因表达芯片有什么优势?

    RNA测序相对基因表达芯片有什么优势? RNA-Seq和基因表达芯片相比,哪种方法更有优势?关键看适用不适用.那么RNA-Seq适用哪些研究方向?是否您的研究?来跟随本文了解一下RNA测序相对基因表达 ...

  10. linux学习第一天 (Linux就该这么学) 找到一本不错的Linux电子书,附《Linux就该这么学》章节目录

    本书是由全国多名红帽架构师(RHCA)基于最新Linux系统共同编写的高质量Linux技术自学教程,极其适合用于Linux技术入门教程或讲课辅助教材,目前是国内最值得去读的Linux教材,也是最有价值 ...