列表

详情


NC52277. 区间求和

描述

小sun最近突然对区间来了兴趣,现在他有这样一个问题想问问你:
给你n个数,每个数为a_i,现在有m个询问,每个询问l,r,需要求出:


num(a_i)代表a_i在这个区间中出现的次数。
你能帮帮他吗?

输入描述

第一行,两个整数n,m

第二行,总共n个数,代表这个数列

接下来m行,每行两个整数l,r,代表一个询问

输出描述

输出总共m行,对于每个询问,输出这个询问对应的答案

示例1

输入:

10 5
1 3 2 4 5 6 4 5 6 7
1 5
2 5
3 4
1 10
3 7

输出:

15
14
6
73
29

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 516ms, 内存消耗: 6372K, 提交时间: 2019-09-15 17:21:29

#include <bits/stdc++.h>
using namespace std;
const int maxn=500000+20;
#define int long long
struct note{
	int l,r,id;
}q[maxn];
int l,r,s,sum,n,m,k;
int ans[maxn],pos[maxn],b[maxn]; 

inline bool cmp(note x,note y){
	if(x.r/s==y.r/s){
		return x.l<y.l;
	}else{
		return x.r<y.r;
	}
}
void add(int x){
	ans[b[x]]++;
	sum+=(ans[b[x]]*2-1)*b[x];
}
void del(int x){
	sum-=(ans[b[x]]*2-1)*b[x];
	ans[b[x]]--;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>b[i];
	}
	s=sqrt(n);
	for(int i=1;i<=m;i++){
		cin>>q[i].l>>q[i].r;
		q[i].id=i;
	}
	sort(q+1,q+m+1,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++){
		int ql=q[i].l,qr=q[i].r;
		while(l<ql)del(l),l++;
		while(l>ql)l--,add(l);
		while(r<qr)r++,add(r);
		while(r>qr)del(r),r--;
		pos[q[i].id]=sum;
	}
	for(int i=1;i<=m;i++){
		cout<<pos[i]<<endl;
	}
}

C++(g++ 7.5.0) 解法, 执行用时: 241ms, 内存消耗: 4980K, 提交时间: 2022-11-09 21:17:50

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

struct node
{
	int l,r,id;
}Q[100005];
long long t=0,l=1,r=0,block,ans[100005],V[100005]={0},a[100005];
bool cmp(node a,node b)
{
	if(a.l/block==b.l/block)return a.r<b.r;
	return a.l/block<b.l/block;
}
void add(int x,int p)
{
	t+=p*a[x]*(2*V[a[x]]+p);
	V[a[x]]+=p;
}
int main()
{
	int i,n,m;
	scanf("%d%d",&n,&m),block=sqrt(n);
	for(i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(i=1;i<=m;i++)scanf("%lld%lld",&Q[i].l,&Q[i].r),Q[i].id=i;
	sort(Q+1,Q+1+m,cmp);
	for(i=1;i<=m;i++)
	{
		while(l<Q[i].l)add(l++,-1);
		while(l>Q[i].l)add(--l,1);
		while(r<Q[i].r)add(++r,1);
		while(r>Q[i].r)add(r--,-1);
		ans[Q[i].id]=t;
	}
	for(i=1;i<=m;i++)printf("%lld\n",ans[i]);
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 276ms, 内存消耗: 6704K, 提交时间: 2020-02-27 11:43:01

#include<bits/stdc++.h>
using namespace std;

struct node
{
	int l,r,id;
}Q[100005];
long long t=0,l=1,r=0,block,ans[100005],V[100005]={0},a[100005];
bool cmp(node a,node b)
{
	if(a.l/block==b.l/block)return a.r<b.r;
	return a.l/block<b.l/block;
}
void add(int x,int p)
{
	t+=p*a[x]*(2*V[a[x]]+p);
	V[a[x]]+=p;
}
int main()
{
	int i,n,m;
	scanf("%d%d",&n,&m),block=sqrt(n);
	for(i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(i=1;i<=m;i++)scanf("%lld%lld",&Q[i].l,&Q[i].r),Q[i].id=i;
	sort(Q+1,Q+1+m,cmp);
	for(i=1;i<=m;i++)
	{
		while(l<Q[i].l)add(l++,-1);
		while(l>Q[i].l)add(--l,1);
		while(r<Q[i].r)add(++r,1);
		while(r>Q[i].r)add(r--,-1);
		ans[Q[i].id]=t;
	}
	for(i=1;i<=m;i++)printf("%lld\n",ans[i]);
	return 0;
}

上一题