bzoj - 2038: [2009国家集训队]小Z的袜子(hose)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj - 2038: [2009国家集训队]小Z的袜子(hose)相关的知识,希望对你有一定的参考价值。

 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2038

 莫队算法可以解决一类不修改、离线查询问题。而这题可以用莫队来做。

 *我是看这个论文学会的:(链接~

 其实莫队就是一种优化的暴力,只是把查询都离线预先按照规则去排序,然后依次暴力处理这些询问。

 有两种做法,目前只会写分段解决。先把1~n分成sqrt(n) , u = sqrt(n) , m个查询先按照第几个块排序,再按照 R排序。

 代码如下:

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 
 7 using namespace std;
 8 const int MAXN = 5e4 + 5;
 9 typedef long long LL;
10 int a[MAXN] , u , cont[MAXN];
11 struct que {
12     int l , r , id;
13 }q[MAXN];
14 struct data {
15     LL x , y;
16 }ans[MAXN];
17 
18 LL gcd(LL x , LL y) {
19     if(!y)
20         return x;
21     return gcd(y , x % y);
22 }
23 
24 bool cmp(que x , que y) {
25     if(x.l / u == y.l / u) 
26         return x.r < y.r;
27     return x.l / u < y.l / u;
28 }
29 
30 inline LL f(LL x) {
31     return x * x;
32 }
33 
34 int main()
35 {
36     int n , m;
37     while(~scanf("%d %d" , &n , &m)) {
38         for(int i = 1 ; i <= n ; i++) {
39             scanf("%d" , a + i);
40         }
41         for(int i = 1 ; i <= m ; i++) {
42             scanf("%d %d" , &q[i].l , &q[i].r);
43             q[i].id = i;
44         }
45         u = sqrt(n);
46         sort(q + 1 , q + m + 1 , cmp);
47         int L = 1 , R = 0;
48         LL temp = 0;
49         memset(cont , 0 , sizeof(cont));
50         for(int i = 1 ; i <= m ; i++) {
51             while(L < q[i].l) {
52                 temp -= f(cont[a[L]]);
53                 cont[a[L]]--;
54                 temp += f(cont[a[L]]);
55                 L++;
56             }
57             while(L > q[i].l) {  //前面的还没算
58                 L--;
59                 temp -= f(cont[a[L]]);
60                 cont[a[L]]++;
61                 temp += f(cont[a[L]]);
62             }
63             while(R > q[i].r) {
64                 temp -= f(cont[a[R]]);
65                 cont[a[R]]--;
66                 temp += f(cont[a[R]]);
67                 R--;
68             }
69             while(R < q[i].r) {
70                 R++;
71                 temp -= f(cont[a[R]]);
72                 cont[a[R]]++;
73                 temp += f(cont[a[R]]);
74             }
75             ans[q[i].id].x = temp - (R - L + 1);
76             ans[q[i].id].y = (LL)(R - L + 1) * (R - L);
77         }
78         for(int i = 1 ; i <= m ; i++) {
79             if(!ans[i].x || !ans[i].y) {
80                 printf("0/1\n");
81             }
82             else {
83                 temp = gcd(ans[i].x , ans[i].y);
84                 printf("%lld/%lld\n" , ans[i].x / temp , ans[i].y / temp);
85             }
86         }
87     }
88 }

 

以上是关于bzoj - 2038: [2009国家集训队]小Z的袜子(hose)的主要内容,如果未能解决你的问题,请参考以下文章

kyeremal-bzoj2038-[2009国家集训队]-小z的袜子(hose)-莫队算法

BZOJ 2038 2009国家集训队 小z的袜子(house)

BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

Bzoj 2038: [2009国家集训队]小Z的袜子(hose)

bzoj 2038: [2009国家集训队]小Z的袜子(hose)