您的位置:首页 > 其它

【BZOJ 2038】小Z的袜子&莫队算法详解

2017-04-17 11:33 295 查看
莫队算法裸题

显然对于一个区间[l,r],可以在O(1)的时间里转移到[l,r+1]或[l,r-1]。

证明:

ans=∑(sum(i)∗(sum(i)−1)/2)(R−L+1)∗(R−L)/2

其中sum(i)表示第i种颜色的袜子的数量,把这个式子化简得到:

ans=∑sum(i)2−(R−L+1)(R−L+1)∗(R−L)

这样我们只要统计p = ∑sum(i)2就可以了。当某一种袜子的颜色从c变成c+1时,p=p−c2+(c+1)2=p+2∗c+1,同理从c变成c-1时,p=p+c2−(c+1)2=p−2∗c−1。也许位运算会快那么一点?(划掉)

然后对整个区间分块,对所有查询双关键字排序,第一关键字为所在的块,第二关键字是查询右端点。然后一个一个加减区间即可。

时间复杂度证明:

左端点的证明:

1、两个查询的左端点在同一块中:每次最多移动N−−√次,一共N次,时间复杂度为O(NN−−√);

2、两个查询不在同一块中:每次跨越相邻块最多要移动2N−−√次,这样的操作最多只有N−−√次,所以时间复杂度为O(N−−√2)。

右端点的证明:

1、两个查询的左端点在同一块中:右端点递增,一共移动N次,一共有N−−√块,时间复杂度为O(NN−−√);

2、两个查询不在同一块中:每次跨越相邻块右端点重新回到左侧,最多移动N次,这样的操作最多只有N−−√次,所以时间复杂度为O(NN−−√)。

#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 100000
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q
;
int block_pos
,sum
,c
;
ll resa
,resb
;
int n,m,i,block,l,r,p;
ll ans,k;
ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}
bool cmp(const query &a,const query &b)
{
if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
return a.l < b.l;
}
void update(int p,int delta)
{
ans = ans + (sum[c[p]] * 2 + delta) * delta;
sum[c[p]] += delta;
}
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,n) scanf("%d",&c[i]);
fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
fo(i,1,m) q[i].id = i;
block = sqrt(n);
fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
sort(q+1,q+m+1,cmp);
l = 1; r = 0;
fo(i,1,m)
{
while (r < q[i].r) {update(r+1,1); r++;}
while (r > q[i].r) {update(r,-1); r--;}
while (l < q[i].l) {update(l,-1); l++;}
while (l > q[i].l) {update(l-1,1); l--;}
p = q[i].id;
resa[p] = ans - (q[i].r - q[i].l + 1);
resb[p] = (ll)(q[i].r - q[i].l + 1) * (q[i].r - q[i].l);
k = gcd(resa[p],resb[p]);
resa[p] /= k; resb[p] /= k;
}
fo(i,1,m) printf("%lld/%lld\n",resa[i],resb[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  莫队算法