• 求和


    洛咕

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

    定义一种特殊的三元组:((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)所得的余数即可,(n,m<=100000).

    分析:首先想了个(n*m)的做法看能不能水过去,只有(60)分,就是枚举位置(i)作为右端点(z)能够产生的贡献,前面扫的时候用一个(vector)记下每种颜色出现的位置,如果前面的位置加上当前位置i是个偶数,就可以计算贡献了.

    前面那种算法对于一些颜色重复计算了多次,我们考虑(i,j,k)三者两两之间都能够产生贡献,则产生的总贡献为((i+j)*(val[i]+val[j])+(i+k)*(val[i]+val[k])+(j+k)*(val[j]+val[k])),整理一下这个式子可以得到(2*(i*val[i]+j*val[j]+k*val[k])+i*(val[j]+val[k])+j*(val[i]+val[k])+k*(val[i]+val[j])).

    这个计算式子是有规律的.然后考虑(i,j,k)需要满足什么条件才能两两之间都能产生贡献呢?颜色相同,奇偶性相同.

    所以我们预处理(vector)数组,(q[i][0/1][j])表示第i种颜色,位置是偶数/奇数的 第j个的 位置.同时处理出(sum[i][0/1])表示第i种颜色,位置是偶数/奇数的 分数之和.

    然后就可以直接枚举每种颜色然后计算贡献了.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int mod=10007;
    const int N=100005;
    int val[N],num[N];
    ll sum[N][2];
    vector<int>q[N][2];
    int main(){
    	int n=read(),m=read();ll ans=0;
    	for(int i=1;i<=n;++i)val[i]=read();
    	for(int i=1;i<=n;++i)num[i]=read();
    	for(int i=1;i<=n;++i){
    		if(i&1){
    			q[num[i]][1].push_back(i);
    			sum[num[i]][1]+=val[i];
    		}
    		else{
    			q[num[i]][0].push_back(i);
    			sum[num[i]][0]+=val[i];
    		}
    	}
    	for(int i=1;i<=m;++i){
    		int tot=q[i][0].size()-1;
    		for(int j=0;j<=tot;++j){
    			ans=(ans+1ll*tot*q[i][0][j]*val[q[i][0][j]]%mod)%mod;
    			ans=(ans+1ll*q[i][0][j]*(sum[i][0]-val[q[i][0][j]])%mod)%mod;
    		}
    		tot=q[i][1].size()-1;
    		for(int j=0;j<=tot;++j){
    			ans=(ans+1ll*tot*q[i][1][j]*val[q[i][1][j]]%mod)%mod;
    			ans=(ans+1ll*q[i][1][j]*(sum[i][1]-val[q[i][1][j]])%mod)%mod;
    		}
    	}
    	/*for(int i=1;i<=n;++i){
    		for(int j=0;j<q[num[i]].size();++j){
    			if((i+q[num[i]][j])&1)continue;
    			ans=(ans+1ll*(i+q[num[i]][j])*(val[i]+val[q[num[i]][j]])%mod)%mod;
    		}
    		q[num[i]].push_back(i);	
    	}*///n*m的做法
    	printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    AFNetworking使用总结
    使用Attiny 85开发板制作BadUSB
    C# 按指定数量从前面或者后面删除字符串
    C# 获取打印机列表
    【解决】该任务映像已损坏或已篡改。(异常来自HRESULT:0x80041321)
    PowerShell 解锁使用浏览器下载的文件
    C#使用HttpHelper万能框架,重启路由器
    【解决】应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序。
    Windows 7 IE11 F12 不能正常使用
    HTML5 图片上传预览
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11622598.html
Copyright © 2020-2023  润新知