zoukankan      html  css  js  c++  java
  • [Noip2015PJ] 求和

    Description

    一条狭长的纸带被均匀划分出了 (n) 个格子,格子编号从 (1)(n) 。每个格子上都染了一种颜色 (color_i)([1,m]) 当中的一个整数表示),并且写了一个数字 (number_i)

    img

    定义一种特殊的三元组:((x,y,z)),其中 (x,y,z) 都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:

    1. (x,y,z) 是整数, (x<y<z)(y-x=z-y)
    2. (color_x=color_z)

    满足上述条件的三元组的分数规定为 ((x+z) imes (number_x+number_z))。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以 (10,007) 所得的余数即可。

    Input

    第一行是用一个空格隔开的两个正整数 (n)(m)(n) 表纸带上格子的个数, (m) 表纸带上颜色的种类数。

    第二行有 (n) 用空格隔开的正整数,第 (i) 数字 (number) 表纸带上编号为 (i) 格子上面写的数字。

    第三行有 (n) 用空格隔开的正整数,第 (i) 数字 (color) 表纸带上编号为 (i) 格子染的颜色。

    Output

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

    Hint

    对 于 全 部 (10) 组 数 据 , (1leq nleq 100000, 1leq mleq 100000, 1leq color_ileq m,1leq number_ileq 100000)

    Solution

    首先能够推导出 (x)(z) 的编号一定是奇偶性相同的。

    所以想到对于奇数点和偶数点分开统计答案。

    拆一下 ((x,y,z)) 三元组对答案产生的贡献:((x+z) imes (number_x+number_z)=x imes number_x+x imes number_z+z imes number_x+z imes number_z)

    观察拆完的式子,发现后边三项中与 (x) 无关的项都能用前缀和维护。

    比如说第二项中的 (x imes number_z,number_z) 显然能用前缀和统计。即扫描到 (x) 节点时它和后面某个点 (z) 对答案在第二项的贡献即为 ((qzh\_number[z]-qzh\_number[x]) imes x)

    所以得到了以下这个基本完成的算法:

    对于每个颜色,分别开两个数组,存储奇数节点和偶数节点的编号,记为 (odd)(even)

    对于每个颜色中的 (even)(odd),再开三个前缀和数组分别维护 (number_z,z,z imes 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
    ",ans%mod);
        return 0;
    }
    
  • 相关阅读:
    警告:ORA-00600 2252 错误正在SCN问题下不断爆发(转)
    Linux批量清除木马文件photo.scr
    500 OOPS: vsftpd: refusing to run with writable root inside chroot() Login failed. 421 Service not available, remote server has closed connection
    Linux后门入侵检测工具(转)
    解决Docker无法删除镜像
    通过DataX从Oracle同步数据到MySQL-安装配置过程
    Server2008 R2安装、配置Freesshd(Jenkins持续集成-Windows)
    Mysql死锁解决办法
    Mssql 2017修改master默认排序规则
    可能需要用到的Mac技巧or软件
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/9088638.html
Copyright © 2011-2022 走看看