您的位置:首页 > 其它

D. Powerful array 莫队算法或者说块状数组 其实都是有点优化的暴力

2015-04-03 20:58 417 查看
莫队算法就是优化的暴力算法。莫队算法是要把询问先按左端点属于的块排序,再按右端点排序。只是预先知道了所有的询问。可以合理的组织计算每个询问的顺序以此来降低复杂度。

                          D. Powerful array

典型的莫队算法题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long LL;
const int INF=0x4fffffff;
const int EXP=1e-5;
const int MS=200005;

int a[MS];
int cnt[5*MS];
LL ans[MS];

struct node
{
int l,r;
int no,qid;
bool operator <(const node &a)const
{
return no<a.no||(no==a.no&&r<a.r);
}
}nodes[MS];

int n,SIZE;
LL res;
int L,R;
LL query(int x,int y,int flag)
{
if(flag)
{
for(int i=x;i<L;i++)
{
res+=(cnt[a[i]]<<1|1)*a[i];
cnt[a[i]]++;
}
for(int i=L;i<x;i++)
{
cnt[a[i]]--;
res-=(cnt[a[i]]<<1|1)*a[i];
}
for(int i=R+1;i<=y;i++)
{
res+=(cnt[a[i]]<<1|1)*a[i];
cnt[a[i]]++;
}
for(int i=y+1;i<=R;i++)
{
cnt[a[i]]--;
res-=(cnt[a[i]]<<1|1)*a[i];
}
}
else
{
for(int i=x;i<=y;i++)
{
res+=(cnt[a[i]]<<1|1)*a[i];
cnt[a[i]]++;
}
}
L=x;R=y;
return res;
}

int main()
{
int Q;
scanf("%d%d",&n,&Q);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);               //   注意%d的速度远大于%I64d的速度
//   在大量数据输入时,能用%d就不要用%I64d,但千万要注意数据溢出
}
SIZE=sqrt(n+0.5);
for(int i=0;i<Q;i++)
{
scanf("%d%d",&nodes[i].l,&nodes[i].r);
nodes[i].no=nodes[i].l/SIZE;
nodes[i].qid=i;
}
sort(nodes,nodes+Q);
memset(cnt,0,sizeof(cnt));
res=0;
for(int i=0;i<Q;i++)
ans[nodes[i].qid]=query(nodes[i].l,nodes[i].r,i);
for(int i=0;i<Q;i++)
printf("%I64d\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐