bzoj2038 小Z的袜子【莫队算法模板+详解】

来源:互联网 发布:linux json 编辑:程序博客网 时间:2024/05/17 03:02

解题思路:

莫队出的模板题。

如果我们知道了询问区间中每种颜色的数量cnti,那么一种颜色的贡献就是C2cnti,总方案数是C2rl+1,每种颜色贡献求和再与总方案数求gcd即可。

关键是如何快速统计区间内每种颜色的数量,这就要用到莫队算法。

考虑建立两个指针l,r,表示区间[l,r]内每种颜色的数量已知。
再将询问离线,按询问左端点所在块(块大小为n)为第一关键字,右端点坐标为第二关键字排序,每次询问一位位暴力挪动l,r指针到该询问左右端点对应位置,同时修改贡献即可(挪一次指针只会改变一种颜色的数量,直接减去原来贡献,加上新贡献),这就是莫队算法,可以证明指针挪动次数为O(nn),证明如下:

先考虑左指针。
当询问左端点在同一块时,每次挪动不超过n次;换块时,最多移动2n次,所以左指针移动次数是O(nn)的。

再考虑右指针。
当询问左端点在同一块时,询问右端点单调递增,一块内最多移动n次;当换块时,右指针最多从n挪回1,也是n次;而整个区间最多会被分为n块,所以右端点移动次数也是O(nn)的。

综上,莫队算法的时间复杂度是O(nn)的。

其实还有带修改的莫队,可以做做bzoj2120,
题解详见http://blog.csdn.net/cdsszjj/article/details/78397256

#include<bits/stdc++.h>using namespace std;int read(){    int i=0,f=1;char c;    for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());    if(c=='-')f=-1,c=getchar();    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';    return i*f;}const int N=50005;int n,m,S,a[N],cnt[N];struct node{    int l,r,id,block;    inline friend bool operator < (const node &a,const node &b)    {return a.block<b.block||a.block==b.block&&a.r<b.r;}}q[N];pair<int,int>ans[N];int gcd(int a,int b){    return b?gcd(b,a%b):a;}int calc(int x){    return 1ll*x*(x-1)/2;}int main(){    //freopen("lx.in","r",stdin);    n=read(),m=read(),S=sqrt(n);    for(int i=1;i<=n;i++)a[i]=read();    for(int i=1;i<=m;i++)    {        q[i].l=read(),q[i].r=read(),q[i].id=i;        q[i].block=(q[i].l-1)/S+1;    }    sort(q+1,q+m+1);    int l=1,r=0,num=0;    for(int i=1;i<=m;i++)    {        int tot=calc(q[i].r-q[i].l+1);        while(l<q[i].l)num=num-calc(cnt[a[l]])+calc(--cnt[a[l]]),++l;        while(l>q[i].l)--l,num=num-calc(cnt[a[l]])+calc(++cnt[a[l]]);        while(r<q[i].r)++r,num=num-calc(cnt[a[r]])+calc(++cnt[a[r]]);        while(r>q[i].r)num=num-calc(cnt[a[r]])+calc(--cnt[a[r]]),--r;        int d=gcd(num,tot);        ans[q[i].id]=make_pair(num/d,tot/d);    }    for(int i=1;i<=m;i++)        cout<<ans[i].first<<'/'<<ans[i].second<<'\n';    return 0;}
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 欧宝威达 山东威达股吧 002026山东威达 威海威达大酒店 002026山东威达股吧 山东威达集团 山东威达股票股吧 广州华威达酒店 山东威达重工股份有限公司 山东威达股票 002026 威迅 威远炮台 威远 威远县 威远楼旅游 四川威远 威远邮编 威远县邮编 威远房价 威远房产网 今日威远 威远招聘网 威远吧 威远人事网 威远零距离 中国威远 威远中学 威远旅行社 威远房地产 威远煤矿 延吉威远 四川威远县 威远在哪里 威远健身房 金威远 自贡威远 威远到成都 威远教育网 威远堡之战 内江威远县