NBUT 1457 分块

2 篇文章 0 订阅
1 篇文章 0 订阅


题目链接: Click_here~

0 0.。。

题目意思就是统计出多少个某个数字出现了多少次。假设 3,1都出现了5次。。 则和是 5*5*5+5*5*5

因为是10秒。。分块无压力。。


#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

#define LL long long
const int N = 133333;
const int Sqrt = 555;
int a[N],b[N],cnt[N],ll[N],rr[N],idx[N];
int n,q;
bool cmp(int x,int y){  
    if(ll[x]/Sqrt == ll[y]/Sqrt)  
        return rr[x] < rr[y];  
    return ll[x] < ll[y];  
}  
LL ret , ans[N] ,F[N];
int main(){
	for(int i = 0;i < N;i++) F[i] = (LL)i*i*i;
	while(scanf("%d",&n)!=EOF){
		memset(cnt,0,sizeof(cnt));
		for(int i = 0;i < n;i++) scanf("%d",a+i);
		memcpy(b,a,sizeof(a));
		sort(b,b+n);
		int sz = unique(b,b+n)-b;
		for(int i=0;i<n;i++) a[i] = lower_bound(b,b+sz,a[i])-b;
		scanf("%d",&q);
		for(int i=0;i<q;i++) idx[i] = i;
		for(int i=0;i<q;i++) scanf("%d %d",&ll[i],&rr[i]);
		sort(idx,idx+q,cmp);
		int ql = 0 , qr = -1;
		ret = 0;
		for(int i=0;i<q;i++){
			int l = ll[idx[i]] , r = rr[idx[i]];
			l--,r--;
			while(qr < r){
				ret -= F[cnt[a[++qr]]];
				ret += F[++cnt[a[qr]]];
			}
			while(ql > l){
				ret -= F[cnt[a[--ql]]];
				ret += F[++cnt[a[ql]]];
			}
			while(qr > r){
				ret -= F[cnt[a[qr]]];
				ret += F[--cnt[a[qr--]]];
			}
			while(ql < l){
				ret -= F[cnt[a[ql]]];
				ret += F[--cnt[a[ql++]]];
			}
			ans[idx[i]] = ret;
		}
		for(int i = 0;i < q;i++)
			//cout << ans[i] << endl;
			printf("%I64d\n",ans[i]);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值