【莫队算法】

〖相关资料

《【莫队算法】》

〖相关题目

1.【bzoj2038】[2009国家集训队]小Z的袜子(hose)

题意:给出n个数与m个区间,在每个区间内选出两个数,求选出的两个数相等的概率。

分析:hzwerの博客

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define LL long long
 6 using namespace std;
 7 const int N=5e4+5;
 8 int n,m,s[N],c[N],pos[N];
 9 LL ans;
10 struct node{int id,l,r;LL a,b;}a[N];
11 int read()
12 {
13     int x=0,f=1;char c=getchar();
14     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
15     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
16     return x*f;
17 }
18 bool cmp(node a,node b)
19 {
20     if(pos[a.l]==pos[b.l])return a.r<b.r;
21     return a.l<b.l;
22 }
23 bool cmp2(node a,node b){return a.id<b.id;}
24 LL sqr(int x){return 1ll*x*x;}
25 LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
26 void update(int p,int val)
27 {
28     ans-=sqr(s[c[p]]);
29     s[c[p]]+=val;
30     ans+=sqr(s[c[p]]);
31 }
32 int main()
33 {
34     n=read();m=read();
35     for(int i=1;i<=n;i++)c[i]=read();
36     int block=(int)sqrt(n);
37     for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1;
38     for(int i=1;i<=m;i++)
39         a[i].l=read(),a[i].r=read(),a[i].id=i;
40     sort(a+1,a+m+1,cmp);
41     for(int i=1,l=1,r=0;i<=m;i++)
42     {
43         for(;r<a[i].r;r++)update(r+1,1);
44         for(;r>a[i].r;r--)update(r,-1);
45         for(;l<a[i].l;l++)update(l,-1);
46         for(;l>a[i].l;l--)update(l-1,1);
47         if(a[i].l==a[i].r){a[i].a=0;a[i].b=1;continue;}
48         a[i].a=ans-(a[i].r-a[i].l+1);
49         a[i].b=1ll*(a[i].r-a[i].l+1)*(a[i].r-a[i].l);
50         LL k=gcd(a[i].a,a[i].b);
51         a[i].a/=k;a[i].b/=k;
52     }
53     sort(a+1,a+m+1,cmp2);
54     for(int i=1;i<=m;i++)printf("%lld/%lld\n",a[i].a,a[i].b);
55     return 0;
56 }
View Code

相关文章: