zoukankan      html  css  js  c++  java
  • 【noip】noip201503求和(题解可能不完美,但绝对详细)

    3. 求和

            难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B

    题目描述

      一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。每个格子上都染了一种颜色colori用[1,m]当中的一个整数表示),并且写了一个数字numberi。
    5
    5
    3
    2
    2
    2
    编号
    1
    2
    3
    4
    5
    6
     
    定义一种特殊的三元组:(x, y, z),其中x,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:
    组要求满足以下两个条件:
        1.  xyz是整数,x<y<z,y-x=z-y
        2.  colorx=colorz
        满足上述条件的三元组的分数规定为(x+z)*(numberx+numberz)。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以10,007所得的余数即可。
     
    【输入输出样例1】
     
    sum.in
    sum.out
    6
    2
           
    82
    5
    5
    3
    2
    2
    2
    2
    2
    1
    1
    2
    1
     
     
    【输入输出样例1 说明】 纸带如题目描述中的图所示。
    所有满足条件的三元组为:(1,3,5),(4,5,6)。
    所以纸带的分数为(1+5)* (5+2)+ (4+6) *(2+2)=42+40=82。
     
    【输入输出样例2】
     
    sum.in
    sum.out
     

    15 4

    5 10 8 2 2 2 9 9 7 7 5 6 4 2 4

    2 2 3 3 4 3 3 2 4 4 4 4 1 1 1

     

     

     
    1388
     
    【数据说明】
    对于第 1 组至第 2 组数据, 1 ≤ n ≤ 100, 1 ≤ m ≤ 5;
    对于第 3 组至第 4 组数据, 1 ≤ n ≤ 3000, 1 ≤ m ≤ 100;
    对于第 5 组至第 6 组数据, 1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000,且不存在出现次数超过 20 的颜色;
    对 于 全 部 10 组 数 据 , 1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, 1 ≤ colori ≤ m,1≤ numberi ≤100000

     

    输入

    第一行是用一个空格隔开的两个正整数n和m,n表纸带上格子的个数,m表纸带上颜色的种类数。
    第二行有n用空格隔开的正整数,第i数字numberi表纸带上编号为i格子上面写的数字。
    第三行有n用空格隔开的正整数,第i数字colori表纸带上编号为i格子染的颜色。

     

    输出

    共一行,一个整数,表示所求的纸带分数除以10,007 所得的余数。

     

    样例输入

    6 2 5 5 3 2 2 2 2 2 1 1 2 1

    样例输出

    82
     
    数学不好的人就别往下看了(友情提示)。
     
     
     
     
     
     
    这题一看就是数学问题。求彩带分数和的式子需要运用一点数学思维化简(化简成计算机能快速算出的)
    比如说:
      设同奇偶且同一种颜色的每个格子中的格子编号为a,b,c,d,....,分数为aa,bb,cc,dd,...
      由于这些格子中要两两计算分数并相加,因此我们来看看能不能把这个数学计算化简下
       
        有两个格子满足条件时的分数和是
            (a+b)*(aa+bb)
         (=0*(a*aa+b*bb)+(a+b)*(aa+bb))
        
        有三个格子满足条件时的分数和是
            (a+b)*(aa+bb)+(a+c)*(aa+cc)+(b+c)*(bb+cc)
           =a*aa+b*bb+c*cc+a*(aa+bb+cc)+b*(aa+bb+cc)+c*(aa+bb+cc) 【把上面那个式子的因式全都分解开,再合并一下,就能合成这样,没难度】
           =a*aa+b*bb+c*cc+(a+b+c)*(aa+bb+cc)
         (=1*(a*aa+b*bb+c*cc)+(a+b+c)*(aa+bb+cc))
        
        有四个格子满足条件时的分数和是
            (a+b)*(aa+bb)+(a+c)*(aa+cc)+(a+d)*(aa+dd)+(b+c)*(bb+cc)+(b+d)*(bb+dd)+(c+d)*(cc+dd)
           =2*(a*aa+b*bb+c*cc+d*dd)+a*(aa+bb+cc+dd)+b*(aa+bb+cc+dd)+c*(aa+bb+cc+dd)+d*(aa+bb+cc+dd)
           =2*(a*aa+b*bb+c*cc+d*dd)+(a+b+c+d)*(aa+bb+cc+dd)
     
      相信接下来大家已经发现规律了:
     
          正常的像(a+b+c+...)*(aa+bb+cc+...)这样的因式的增项就不说了,主要是注意每多一个格子满足条件时,每个格子就多加一次自身的编号和数字((?)*(a*aa+b*bb+...)
      因此用数(哲♂)学做法:
          设ci为格子颜色,j为0时表示这些三元组的x,z均为偶数,j为1时则均为奇数。
          设之前出现过的与之同奇偶p同颜色ci的格子数设为cnt[ci][p],
          格子序号和color[ci][0][p],格子数字和color[ci][1][p],格子序号与数字之积之和为color[ci][2][p]。
          当所有格子(所有颜色的格子)满足条件时,分数和为
             for(i=1;i<=m;i++)
                 for(j=0;j<=1;j++){
                     sum+=color[i][0][j]*color[i][1][j]+((cnt[i][j]-2)*color[i][2][j]);
                     sum%=10007;

                 }

     

    #include<iostream>
    #include<cstring>
    #define maxn 100005
    using namespace std;
    long long color[maxn][3][2],number[maxn],cnt[maxn][2],n,m,sum;
    /*
    之前出现过的与之同奇偶p同颜色ci的格子数设为cnt[ci][p],
    格子序号和color[ci][0][p],格子数字和color[ci][1][p],格子序号与数字之积之和为color[ci][2][p]
    */
    int main(){
        int cor,i,j;
        scanf("%lld%lld",&n,&m);
        for(i=1;i<=n;i++) scanf("%lld",&number[i]);
        for(i=1;i<=n;i++){
            scanf("%d",&cor);
            cnt[cor][i&1]++;
            (color[cor][0][i&1]+=i)%=10007;
            (color[cor][1][i&1]+=number[i])%=10007;
            (color[cor][2][i&1]+=number[i]*i)%10007;
        }
        for(i=1;i<=m;i++)
            for(j=0;j<=1;j++){
                sum+=(color[i][0][j]*color[i][1][j])%10007+((cnt[i][j]-2)*color[i][2][j])%10007;
                sum%=10007;
            }
        printf("%lld
    ",sum);
        system("pause");
        return 0;
    }
    

      我也查了网上别人的题解,我相信我这是最详细的了,因为我抠了一个多小时这题→_→

  • 相关阅读:
    mysql中的where和having的区别
    php解决前后端验证字符串长度不一致
    复习
    SQL语句执行顺序
    领域驱动设计(DDD)
    什么是ORM?为啥要是用ORM?
    Python web框架搭建
    Python web自动化环境搭建
    Jmeter录制手机app脚本
    Charles截取 Https 通讯信息
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/noip201503.html
Copyright © 2011-2022 走看看