【序列莫队】BZOJ2038- [2009国家集训队]小Z的袜子(hose)

【题目大意】
给出1-N只袜子的颜色,多次询问L-R中选出一双同色袜子的概率。

【思路】

裸莫队。基本的莫队步骤:
①分组(每组大小为根号sqrt(n),共sqrt(n)组)
②排序(左边界分组,右边界在组内按大小排序)
③暴力转移

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int MAXN=50000+50;
 8 typedef long long ll;
 9 struct node
10 {
11     int l,r,id,pos;
12     ll ansa,ansb;
13 };
14 int n,m,c[MAXN];
15 ll ans=0,s[MAXN];
16 ll sqr(ll x){return x*x;}  
17 node q[MAXN];
18  
19 ll gcd(ll a,ll b)
20 {
21     if (b==0) return a;
22         else return gcd(b,a%b);
23 }
24  
25 bool cmp(node a,node b)
26 {
27     if (a.pos==b.pos) return (a.r<b.r);
28         else return (a.pos<b.pos);
29 }
30  
31 bool cmp_id(node a,node b)
32 {
33     return (a.id<b.id);
34 }
35  
36 void update(int x,int delta)
37 {
38     ans-=sqr(s[c[x]]);
39     s[c[x]]+=delta;
40     ans+=sqr(s[c[x]]);
41 }
42  
43 void init()
44 {
45     memset(s,0,sizeof(s));
46     memset(c,0,sizeof(c));
47     scanf("%d%d",&n,&m);
48     for (int i=1;i<=n;i++) scanf("%d",&c[i]);
49     int block=int(sqrt(n));
50     for (int i=0;i<m;i++)
51     {
52         scanf("%d%d",&q[i].l,&q[i].r);
53         q[i].id=i;
54         q[i].pos=(q[i].l-1)/block+1;
55     }
56     sort(q,q+m,cmp);
57 }
58  
59 void solve()
60 {
61     int l=1,r=1;
62     s[c[1]]=1,ans=sqr(s[c[1]]);
63     for (int t=0;t<m;t++)
64     {
65         for (;r<q[t].r;r++) update(r+1,1);
66         for (;r>q[t].r;r--) update(r,-1);
67         for (;l<q[t].l;l++) update(l,-1);
68         for (;l>q[t].l;l--) update(l-1,1);
69         if (l==r)
70         {
71             q[t].l=0;q[t].r=1;
72             continue;
73         }
74         q[t].ansa=ans-(r-l+1);
75         q[t].ansb=(ll)(r-l+1)*(r-l);
76         ll minx=min(q[t].ansa,q[t].ansb),maxx=max(q[t].ansa,q[t].ansb);
77         ll k=gcd(maxx,minx);
78         q[t].ansa/=k,q[t].ansb/=k;
79     }
80 }
81  
82 void print()
83 {
84     sort(q,q+m,cmp_id);
85     for (int i=0;i<m;i++) printf("%lld/%lld\n",q[i].ansa,q[i].ansb);
86 }
87  
88 int main() 
89 {
90     init();
91     solve();
92     print(); 
93     return 0;
94 }

 

posted @ 2016-07-17 22:53  iiyiyi  阅读(179)  评论(0编辑  收藏  举报