F - An Average Game(莫队3)

Alice and Bob has just learned how to find average of some numbers. They got really excited and decided to come up with a game about finding average. The game works like this, at the start of game a sequence of numbers is written. Then there will be several rounds in the game. In first round Alice will say a number x and Bob has to select two index i and j. Let’s say the average of the unique numbers between i-th number and j-th number is y. Then Alice gets abs(x− y) points in that round. In next round Alice and Bob switch the role. The game continues this way. While Alice and Bob enjoy playing this game, they hate calculating average of unique numbers. So, they are asking you, their only programmer friend, to write a program that calculates the average for them

Input

First line of input is a number T (T ≤ 100). T test cases follow. First line of each test case is an integer n (0 < n < 104 ) representing the length of number sequence. Next line consists n space separated integer representing the sequence. Each of these integers has absolute value less than 109 . Next line has an integer q (q < 105 ). q lines follow, each representing a query. Each query has two space separated integer i, j (1 ≤ i ≤ j ≤ n)..

Output

For each case output q lines representing average of unique elements of corresponding range rounded 6 digits after decimal points. No case will have output whose rounding changes if the 10−9 is added to or subtracted from answer.

 Notes: Explanation for second query in first sample The range is (1,10) which includes ten numbers (1, 2, 3, 4, 4, 3, 2, 1, -1, 0). Unique numbers in this ranges are (1, 2, 3, 4, -1, 0) whose average is 1.5 Explanation for third query in first sample The range is (3,5) which includes three numbers (3, 4, 4). Unique numbers in this ranges are 3 and 4 whose average is 3.5

Sample Input

2

10

1  2  3  4  4  3  2  1  -1  0 

4

1  4

1 10

3 5

8 10

3

1 1 0

1

1 3

题目大意:求各区间的平均值

坑点:题目是大佬给我讲的,没有看数据,区间元素用map存,不然就会疯狂疯狂疯狂re!!!!!

别问我为什么知道 你懂得

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
const double pi = acos(-1.0);
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + 5;
int n, m;
double ans, sum;//这里得开double,别问我怎么知道,我也心痛过
int belong[maxn], a[maxn];
map<int, int> num;//这里的用map,要不会RE的,数太大啦
double re[maxn];
struct node
{
    int l, r, id;
}q[maxn];
void build()
{
    int block = sqrt(n);
    for(int i=1;i<=n;i++)
    {
        belong[i] = (i-1) / block + 1;
    }
}
bool cmp(node a, node b)
{
    if(belong[a.l] == belong[b.l]) return a.r < b.r;
    else return belong[a.l] < belong[b.l];
}
void add(int x)
{
    if(!num[x]) sum += x, ans++;
    num[x]++;
}
void del(int x)
{
    if(num[x] == 1) sum -= x, ans--;
    num[x]--;
}
int main()
{
    int t;
    scanf("%d", &t);
    int k = 1;
    while(t--)
    {
        ans = 0, sum = 0;
        num.clear();
        memset(a, 0, sizeof(a));
        memset(belong, 0, sizeof(belong));
        memset(re, 0, sizeof(re));
        scanf("%d", &n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d", &a[i]);
        }
        build();
        scanf("%d", &m);
        for(int i=1;i<=m;i++)
        {
            q[i].id = i;
            scanf("%d %d", &q[i].l, &q[i].r);
        }
        sort(q+1, q+m+1, cmp);
        int l = 1, r = 0;
        for(int i=1;i<=m;i++)
        {
            int ql = q[i].l;
            int qr = q[i].r;
            while(r < qr)
            {
                add(a[++r]);
            }
            while(r > qr)
            {
                del(a[r--]);
            }
            while(l < ql)
            {
                del(a[l++]);
            }
            while(l > ql)
            {
                add(a[--l]);
            }
            if(ans != 0)
            {
                re[q[i].id] = (double)((sum * 1.0 ) / (ans * 1.0));
            }
            else re[q[i].id] = 0;
        }
        printf("Case %d:\n", k++);
        for(int i=1;i<=m;i++)
        {
            printf("%.6f\n", re[i]);
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值