您的位置:首页 > 编程语言 > Go语言

Yandex.Algorithm 2011 Round 2-D - Powerful array-莫队算法(分块算法)

2016-05-13 17:31 555 查看
http://codeforces.com/contest/86/problem/D

莫队算法就是处理这类能O1从区间【l,r】得到 【l-1,r】【l,r+1】,不带修改的区间查询的一类问题。

题目要求任意 subarray 的 cnt[a[i]]*cnt[a[i]]*a[i]

按照套路,把所有区间按 左端点 所在块作第一关键字,右端点第二关键字 排序

遍历,预处理第一次询问后,每次询问暴力求解,转移如下:

  res -= cnt[a[i]]*cnt[a[i]]*a[i];

            cnt[a[i]]++;

            res += cnt[a[i]]*cnt[a[i]]*a[i];

算法复杂度为q*sqrt n 

考虑右指针,先是按照递增顺序移动,假设当前块右指针在最右端,当下一块时,需移动到最左端,那么也就是每跨越一个块,最多移动O(N),总共sqrtn个块,复杂度n*sqrtn

考虑左指针如果在同一块,移动量不超过sqrtn【在一块内嘛】

如果是跨越一块,移动量最多不超过2*sqrtn【块长只有sqrtn】

复杂度(q*sqrtn)

总复杂度(q+n)*sqrtn

----------------------------------------------------------

有一点 add move 的时候直接那刚才的暴力转移会超时,

因为每次变化只有1, 也就是 x*x*a 变成 (x+1)*(x+1)*a,显然我们直接加上 a*(2*x+1)就好了。。。最后跑了 1.9S

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
#define N 200100
typedef long long ll;
int a
, cnt[N*5];
ll ans
, res;
int L, R;

struct node
{
int x, y, l, p;
} q
;
bool cmp(const node &x, const node &y)
{
if (x.l == y.l) return x.y < y.y;
return x.l < y.l;
}
void query(int x, int y, int flag)
{
if (flag)
{
for (int i=x; i<L; i++)
{
res += (cnt[a[i]]*2+1)*a[i];
cnt[a[i]]++;
}
for (int i=L; i<x; i++)
{
res += (-cnt[a[i]]*2+1)*a[i];
cnt[a[i]]--;
}
for (int i=y+1; i<=R; i++)
{
res += (-cnt[a[i]]*2+1)*a[i];
cnt[a[i]]--;
}
for (int i=R+1; i<=y; i++)
{
res += (cnt[a[i]]*2+1)*a[i];
cnt[a[i]]++;
}

}
else
{

for (int i=x; i<=y; i++)
{
res += (cnt[a[i]]*2+1)*a[i];
cnt[a[i]]++;
}
}
L = x, R = y;
}
int main()
{
int n, t;

scanf("%d%d", &n, &t);
for (int i=1; i<=n; i++) scanf("%d", &a[i]);
int block_size = sqrt(1.0*n);

for (int i=0; i<t; i++)
{
scanf("%d%d", &q[i].x, &q[i].y);
q[i].l = q[i].x / block_size;
q[i].p = i;
}
sort(q, q+t, cmp);

res = 0;
for (int i=0; i<t; i++)
{
query(q[i].x, q[i].y, i);
ans[q[i].p] = res;
}

for (int i=0; i<t; i++) printf("%I64d\n", ans[i]);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: