【CF 86D】Powerful array

题目来源:Codeforces 86D

翻译:

描述

给出一个正整数序列 a1,a2,...,an 。 我们考虑它的子序列 al,al+1...,ar ,其中 1lrn Ks 表示数字 s 在序列中出现的次数。我们把一个序列的权值记作:

K2ss
其中,s为序列中含有的数。
你需要计算t组询问。

输入

第一行包含两个整数 N T(1 ≤ N, T ≤ 200000)分别表示数组的长度和相应的查询数。
第二行包含 N 个正整数(1ai106) 表示数组的元素。
接下来 T 行,每行包含两个正整数LR (1LRn) 表示每个询问的左、右端点。

输出

一行一个数,t行,表示答案。

思路:

类似于小Z的袜子,考虑直接分块做。
用作初学分块的强化练习。
竟然卡常数,醉。

代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 200010;
inline ll get(){
    char c = ' '; ll num = 0; int op = 1, ok = 0;
    while(1){
        c = getchar();
        if(c == '-') op = -1;
        if(c <= '9' && c >= '0') num = num * 10 + c - '0', ok = 1;
        else if(ok) return num * op;
    }
}
struct node{
    int l, r, id; ll res;
}v[maxn];
int each, n, m, pos[maxn];
ll c[maxn], s[maxn*5], res;
inline bool cmp(node a, node b){return pos[a.l] == pos[b.l] ? a.r < b.r : a.l < b.l;}
inline bool cmp_id(node a, node b){return a.id < b.id;}
inline void update(int p, int k){
    res += (ll)(c[p]*s[c[p]]*k*2 + c[p]*k*k);
    s[c[p]] += k;
}
int main(){
    scanf("%d%d", &n, &m), each = (ll)sqrt(n);
    for(int i = 1; i <= n; i ++) c[i] = get();
    for(int i = 1; i <= n; i ++) pos[i] = (i-1)/each+1;
    for(int i = 1; i <= m; i ++) v[i].l = get(), v[i].r = get(), v[i].id = i;
    sort(v+1, v+1+m, cmp);
    for(int i = 1, l = 1, r = 0; i <= m; i ++){
        for( ; r < v[i].r; r ++) update(r+1, 1);
        for( ; r > v[i].r; r --) update(r, -1);
        for( ; l < v[i].l; l ++) update(l, -1);
        for( ; l > v[i].l; l --) update(l-1, 1);
        v[i].res = res;
    } sort(v+1, v+1+m, cmp_id);
    for(int i = 1; i <= m; i ++) printf("%I64d\n", v[i].res);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值