51nod1712 区间求和

本文介绍了一种关于区间求和的算法题解,探讨了如何高效地计算序列中特定条件下的权值和,并通过实例说明了解题思路及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基准时间限制:1 秒 空间限制:131072 KB 分值: 80  难度:5级算法题
 收藏
 关注
LYK在研究一个有趣的东西。
假如有一个长度为n的序列,那么这个序列的权值将是所有有序二元组i,j的  Σajai 其中1<=i<j<=n。
但是这个问题似乎太简单了。
于是LYK想在所有有序二元组k,l中若 ak=al其中1<=k<l<=n, 则将 a{k},a{k+1},...,a{l}  提出当做一个序列,计算它的权值。
并统计所有这样的区间的权值和。
由于答案可能很大,你只需要将答案对2^32取模即可。
建议使用读入优化。
Input
第一行一个整数n(1<=n<=1000000),接下来一行n个数ai(1<=ai<=1000000)表示LYK的序列。
Output
一行表示答案。
Input示例
5
3 4 5 5 3
Output示例
2
alpq654321  (题目提供者)



题解:

对于一个区间l~r,我们可以发现第x个数贡献的次数为x*2-l-r((x-l)-(r-x)),然后我们用很恶心的瞎几把搞O(n)的处理判断下就行了。

PS:如果你对自己的常数足够自信,那你可以不用读入优化(反正我是要用的)


代码:


#include<bits/stdc++.h>
using namespace std;
long long n,i,ans,p,a[1000001],bs[1000001],bn[1000001],rss[1000001],rsn[1000001],lss[1000001],lsn[1000001],sumsl[1000001],sumsr[1000001],sumnl[1000001],sumnr[1000001];
long long read()
{
    long long x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int main(){
	scanf("%lld",&n);
	for(i=1;i<=n;i++){
	a[i]=read();
}
p=1024ll*1024*1024*4;
//printf("%lld\n",p);
    for(i=1;i<=n;i++){
    	rss[i]+=bs[a[i]]+i*bn[a[i]];
    	rsn[i]=bn[a[i]];
    	bn[a[i]]++;bs[a[i]]+=i;
	}
	//printf("-1\n");
	memset(bn,0,sizeof(bn));
	memset(bs,0,sizeof(bs));
	for(i=n;i;i--){
		lss[i]+=bs[a[i]]+i*bn[a[i]];
		lsn[i]=bn[a[i]];
		bn[a[i]]++;bs[a[i]]+=i;
}
//printf("-2\n");
	for(i=n;i;i--)sumsl[i]=sumsl[i+1]+rss[i];
	for(i=n;i;i--)sumsr[i]=sumsr[i+1]+lss[i];
	for(i=n;i;i--)sumnl[i]=sumnl[i+1]+rsn[i];
	for(i=n;i;i--)sumnr[i]=sumnr[i+1]+lsn[i];
	//printf("%lld\n",p);
	for(i=1;i<=n;i++){
		//printf("%lld %lld %lld %lld %lld %lld\n",i,sumnl[i],sumnr[i+1],sumsl[i],sumsr[i+1],a[i],p);
		ans=(ans+((((sumnl[i]-sumnr[i+1])*2*i-sumsl[i]+sumsr[i+1]))*a[i])%p)%p;
	}
	printf("%lld",ans);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值