码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-07-21 22:03:34      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

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

题意:

把N只袜子从1到N编号,每次求从编号为L到R的袜子中抽两只,有多大的概率抽到颜色相同的袜子。

题解:

不知道要用什么数据结构,但是可以用一个全局的数组保存每个颜色当前数量,使由区间[l,r]推出[l,r±1]的答案和[l±1,r]的复杂度为O(1),对这种问题,可以用复杂度为O(nsqrt(n))的莫队算法解决。

莫队算法是一种离线算法,将询问按某种顺序排序,使得均摊复杂度为O(nsqrt(n)),那怎么排序呢?如果按左端点排序,那么r将有可能多次大幅度摆动,使复杂度退化成O(n^2),正解是对端点分块,让后按左端点所在块为第一关键字排序,右端点为第二关键字排序。这样子当两个询问l在同一块时,l只有可能移sqrt(n)次。l在同一块的多次询问q只能右移n次,l在不同块时r可能左移n次,但因为只有sqrt(n)块,所以需移n次的操作都只有sqrt(n)次,因此均摊复杂度是O(sqrt(n))。所有的均摊复杂度都是玄学……

因为中间结果没有强制转化成long long,wa了好几发,本弱太弱了!

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 #define ll long long
 6 #define inc(i,j,k) for(int i=j;i<=k;i++)
 7 using namespace std;
 8 
 9 struct nd1{
10     int l,pl,r,id; ll ans;
11 };
12 bool cmp1(nd1 a,nd1 b){
13     if(a.pl!=b.pl)return a.pl<b.pl; if(a.r!=b.r)return a.r<b.r;
14     return a.l<b.l;
15 }
16 bool cmp2(nd1 a,nd1 b){
17     return a.id<b.id;
18 }
19 nd1 a1[100000];int col[100000],pos[100000],n,m,l,r;ll ans,s[100000];
20 inline void update(int x,int y){
21     ans-=(s[col[x]]*(s[col[x]]-1));s[col[x]]+=(ll)y;ans+=(s[col[x]]*(s[col[x]]-1));
22 }
23 ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
24 int main(){
25     scanf("%d%d",&n,&m); inc(i,1,n)scanf("%d",&col[i]); int sz=(int)sqrt(n);
26     inc(i,1,n)pos[i]=(i-1)/sz+1;
27     inc(i,1,m){
28         int a,b;scanf("%d%d",&a,&b);a1[i]=(nd1){a,pos[a],b,i,0};
29     }
30     sort(a1+1,a1+1+m,cmp1); l=1; r=0; ans=0; memset(s,0,sizeof(s));
31     inc(i,1,m){
32         while(r<a1[i].r)update(r+1,1),r++;
33         while(l>a1[i].l)update(l-1,1),l--;
34         while(r>a1[i].r)update(r,-1),r--;
35         while(l<a1[i].l)update(l,-1),l++;
36         a1[i].ans=ans;
37     }
38     sort(a1+1,a1+1+m,cmp2); 
39     inc(i,1,m){
40         if(a1[i].ans==0)printf("0/1\n");else{
41             ll a2=gcd(a1[i].ans,(ll)(a1[i].r-a1[i].l+1)*(a1[i].r-a1[i].l));
42             printf("%lld/%lld\n",a1[i].ans/a2,(ll)(a1[i].r-a1[i].l+1)*(a1[i].r-a1[i].l)/a2);
43         }
44     }
45     return 0;
46 }

 

20160405

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

标签:

原文地址:http://www.cnblogs.com/YuanZiming/p/5693162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!