zoukankan      html  css  js  c++  java
  • P2671 求和 (NOIP 2015)

    传送门

    分析

    • 40 pts : (O(n^2))

      将原先的 (y-x = z-y) 化为 (2 imes y = x + z) ,只要暴力枚举 (x,z) 即可

    • 100 pts: (O(n))

      通过 40 分的做法,我们可以发现,对于一个符合要求的 (y) ,必须要 (x,z) 保持同号

      那么我们不妨可以假设存在集合 (A) ,是得该集合内的所有元素(方格)为同种颜色,且符号相同的

      于是,我们可以整理出这么一个式子:对于集合内的元素 (x_i) ,有 ((x_1 + x_2) * (num_1+num_2) + (x_1+x_3)*(num_1+num_3)+ …… +(x_1+x_n)*(num_1+num_n)+……+(x_{n-1}+x_n)*(num_{n-1}+num_{n}))

      对于这个毫无规律的式子,我们可以先研究它的所有包含 (x_1) 的项,将其全部提出,可得 (i_1*num_1 + i_1*num_2 +i_1*num_1+i_1*num_3+……+i_1*num_1+i_1*num_n)

      进一步合并为 (i_1*num_1*(n-1)+i_1*(num_2+num_3+num_4+……+num_n))

      那么:我们可以归纳出这样一个式子:假设该种集合中共有 (k) 项,对于第 (n) 项,有 (i_n*num_n*(k-1)+i_n*(num_1+num_2+……+num_{n-1}+num_{n+1}+……+num_{k}))

      对于这一串式子,可以先将其加上一个 (i_n*num_n),再减去一个 (i_n*num_n)

      即为:(i_n*num_n*(k-2)+i_n*(num_1+num_2+……+num_{n-1}+num_n+num_{n+1}+……+num_{k}))

      对于 ((num_1+num_2+……+num_{n-1}+num_n+num_{n+1}+……+num_{k})),我们可以直接前缀和处理得到


    源代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<math.h>
    #define ll long long
    using namespace std;
    
    const ll mod=10007;
    const ll maxn=1e5+10;
    ll n,m,ans;
    ll sum1[maxn][2];
    ll sum2[maxn][2];
    struct node
    {
    	ll num,c;
    } s[maxn];
    
    int main(void)
    {
    	scanf("%lld%lld",&n,&m);
    	
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&s[i].num);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&s[i].c);
    		sum1[s[i].c][i%2]++;
    		(sum2[s[i].c][i%2]+=s[i].num)%=mod;
    	}
    	
    	for(int i=1;i<=n;i++)
    	{
    		(ans+=(i*((sum1[s[i].c][i%2]-2)*s[i].num+sum2[s[i].c][i%2])))%=mod;
    	}
    	
    	printf("%lld
    ",ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    Hadoop(1.2.1)安装
    ETL,BPM与ESB三者的一些感悟
    编程上面的理论支撑
    TreeSet类的排序
    List接口
    Map接口
    类和对象
    面向对象1
    IO流4
    Java面向对象
  • 原文地址:https://www.cnblogs.com/jd1412/p/13619806.html
Copyright © 2011-2022 走看看