莫队算法

#include <bits/stdc++.h>
#define PB push_back
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define PI acos((double)-1)
#define E exp(double(1))
#define K 100000+9
int a[K],vis[K],pos[K*10];
int sz,n,m;
double ans[K*10],sum,num;
map<int,int>p;
struct node
{
    int l,r,id;
}q[K*10];
int cmp(node ta,node tb)
{
    if(pos[ta.l]==pos[tb.l])return ta.r<tb.r;
    return pos[ta.l]<pos[tb.l];
}
void add(int x)
{
    if(!vis[p[a[x]]])sum+=a[x],num++;
    vis[p[a[x]]]++;
}
void del(int x)
{
    if(vis[p[a[x]]]==1)sum-=a[x],num--;
    vis[p[a[x]]]--;
}
void slove(void)
{
    int l,r;
    l=1;r=0;
    sum=num=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=m;i++)
    {
        while(l<q[i].l)del(l++);
        while(l>q[i].l)add(--l);
        while(r<q[i].r)add(++r);
        while(r>q[i].r)del(r--);
        ans[q[i].id]=sum*1.0/num;
    }
}

int main(void)
{
    int t,cs=1;
    cin>>t;
    while(t--)
    {
        scanf("%d",&n);
        p.clear();
        for(int i=1,cnt=1,x;i<=n;i++)
        {
            scanf("%d",&x);
            if(p[x]==0)p[x]=cnt++;
            a[i]=x;
        }
        scanf("%d",&m);
        sz=sqrt(n);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&q[i].l,&q[i].r);
            pos[q[i].l]=(q[i].l-1)/sz+1;
            q[i].id=i;
        }
        sort(q+1,q+m+1,cmp);
        slove();
        printf("Case %d:\n",cs++);
        for(int i=1;i<=m;i++)
            printf("%.6f\n",ans[i]);
    }

    return 0;
}

 

posted @ 2016-07-24 11:27  weeping  阅读(396)  评论(0编辑  收藏  举报