An Average Game(分块+莫队)

 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 < 1e4) 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 1e9. Next line has an integer q (q < 1e5). 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 10e−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

Sample Output
Case 1:
2.500000
1.500000
3.500000
0.000000
Case 2:
0.500000

题意:
对已知数组,求给定区间内不同的数的平均值

思路:
分块用莫队,跟Group一样,就是多了个求不同数字种数

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 map<int, int>coun;       //队友说过,map啥都能干,,,这里数太大1e9,个数也就1e4
 6                  //身为c语言钉子户,写的东西多了,咱还真就得认,c++就是方便点
 7 struct node
 8 {
 9     int left, right, num;
10 }str[100005];
11 int a[10005], belong[10005], number;
12 
13 bool cmp(struct node x, struct node y)
14 {
15     if(belong[x.left]==belong[y.left]) return x.right < y.right;
16     else return x.left < y.left;
17 }
18 
19 double add(int n, double sum)
20 {
21     if(coun[n]==0)
22     {
23         sum += n;
24         number++;
25     }
26     coun[n]++;
27     return sum;
28 }
29 
30 double subtract(int n, double sum)
31 {
32     coun[n]--;
33     if(coun[n]==0)
34     {
35         number--;
36         sum -= n;
37     }
38     return sum;
39 }
40 
41 int main()
42 {
43     int n, m, t, i, temp, l, r, j;
44     double re[100005], sum;   //一开始sum定义成int,WA了,改成double就对了,不知道什么情况
45     scanf("%d", &t);
46     for(j=1;j<=t;j++)
47     {
48         coun.clear();        //coun清零
49         scanf("%d", &n);
50         temp = sqrt(n);
51         for(i=1;i<=n;i++)
52         {
53             scanf("%d", &a[i]);
54             belong[i] = (i-1) / temp + 1;
55         }
56         scanf("%d", &m);
57         for(i=1;i<=m;i++)
58         {
59             str[i].num = i;
60             scanf("%d %d", &str[i].left, &str[i].right);
61         }
62         sort(str+1, str+m+1, cmp);
63         l = 1;
64         r = 0;
65         sum = 0;
66         number = 0;
67         for(i=1;i<=m;i++)
68         {
69             while(r<str[i].right)
70             {
71                 r++;
72                 sum = add(a[r], sum);
73             }
74             while(r>str[i].right)
75             {
76                 sum = subtract(a[r], sum);
77                 r--;
78             }
79             while(l<str[i].left)
80             {
81                 sum = subtract(a[l], sum);
82                 l++;
83             }
84             while(l>str[i].left)
85             {
86                 l--;
87                 sum = add(a[l], sum);
88             }
89             re[str[i].num] = 1.0 * sum / number;
90         }
91         printf("Case %d:\n", j);
92         for(i=1;i<=m;i++)
93         {
94             printf("%.6f\n", re[i]);
95         }
96     }
97     return 0;
98 }

 

posted @ 2019-08-04 14:11  Xxiaoyu  阅读(186)  评论(0编辑  收藏  举报