bzoj2038 小Z的袜子(hose)——莫队算法
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2038
就是莫队算法;
先写了个分块,惨WA:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=;
int n,m,K,c[maxn],rk[maxn],cnt[maxn],cnt2[maxn],ct=,t,tmp[maxn];
ll sum,s;
struct N{int l,r;ll ans,ans2;}q[maxn];
int rd()
{
int ret=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret;
}
bool cmp(int x,int y){return q[x].l<q[y].l;}
bool cmp2(int x,int y){return q[x].r<q[y].r;}
int C(int x){return x*(x-)/;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void yf(N &x)//&
{
ll k=gcd(x.ans2,x.ans);
x.ans/=k;x.ans2/=k;
}
void solve(int k)
{
sort(tmp+,tmp+t+,cmp2);
sum=;
memset(cnt,,sizeof cnt);
int L=k*K,R=L+;
for(int i=;i<=t;i++)
{
memset(cnt2,,sizeof cnt2);
while(R<=q[tmp[i]].r)
{
sum+=cnt[c[R]];cnt[c[R]]++;R++;
}
s=sum;
for(int j=L;j>=q[tmp[i]].l;j--)
{
s+=cnt[c[j]]+cnt2[c[j]];cnt2[c[j]]++;
}
q[tmp[i]].ans=s;
q[tmp[i]].ans2=C(q[tmp[i]].r-q[tmp[i]].l+);
yf(q[tmp[i]]);
}
}
int main()
{
n=rd();m=rd();K=sqrt(n);
for(int i=;i<=n;i++)c[i]=rd();
for(int i=;i<=m;i++)q[i].l=rd(),q[i].r=rd(),rk[i]=i;
sort(rk+,rk+m+,cmp);
for(int i=;(i-)*K<n;i++)
{
t=;
while(q[rk[ct]].l<=i*K&&ct<=m)tmp[++t]=rk[ct],ct++;
solve(i);
}
for(int i=;i<=m;i++)
printf("%lld/%lld\n",q[i].ans,q[i].ans2);
return ;
}
囧
然后看了看题解,竟然是另一种做法,处理了一下式子:https://www.cnblogs.com/MashiroSky/p/5914637.html
所以抄了一下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=;
int n,m,K,c[maxn],cnt[maxn],blk[maxn];
ll ans;
struct N{int l,r,bh;ll a,b;}q[maxn];
int rd()
{
int ret=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret;
}
bool cmp(N x,N y){return blk[x.l]==blk[y.l]?x.r<y.r:blk[x.l]<blk[y.l];}
bool cmp2(N x,N y){return x.bh<y.bh;}
ll gcd(ll a,ll b){return a%b==?b:gcd(b,a%b);}
void update(int x,int val)
{
ans-=cnt[c[x]]*cnt[c[x]];
cnt[c[x]]+=val;
ans+=cnt[c[x]]*cnt[c[x]];
}
int main()
{
n=rd();m=rd();K=sqrt(n);
for(int i=;i<=n;i++)c[i]=rd(),blk[i]=(i-)/K+;;
for(int i=;i<=m;i++)q[i].l=rd(),q[i].r=rd(),q[i].bh=i;
sort(q+,q+m+,cmp);
for(int i=,l=,r=;i<=m;i++)
{
while(l<q[i].l)update(l,-),l++; while(l>q[i].l)update(l-,),l--;
while(r<q[i].r)update(r+,),r++; while(r>q[i].r)update(r,-),r--;
if(q[i].l==q[i].r)
{
q[i].a=;q[i].b=;continue;
}
q[i].a=(ll)ans-(r-l+); q[i].b=(ll)(r-l+)*(r-l);//(ll)!!!
ll k=gcd(q[i].a,q[i].b);//把分子放前面,万一分子是0
q[i].a/=k; q[i].b/=k;
}
sort(q+,q+m+,cmp2);
for(int i=;i<=m;i++)
printf("%lld/%lld\n",q[i].a,q[i].b);
return ;
}
...
然后又看到一篇博客:https://www.cnblogs.com/xuwangzihao/p/5199174.html
我的想法还是可以的嘛,加入一个点就是增加了之前有的这种点个数那么多的点对,所以维护点的个数即可;
主要是这个题不用严格按照分块来做,只是按分块排一下序就可以保证时间复杂度了,所以 l 和 r 直接全局移动就可以;
这样的话代码突然变得好优美...说到底自己那样的分块还是写得太丑,都不能保证正确呢...
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=;
int n,m,K,c[maxn],cnt[maxn],blk[maxn];
ll ans;
struct N{int l,r,bh;ll a,b;}q[maxn];
int rd()
{
int ret=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret;
}
bool cmp(N x,N y){return blk[x.l]==blk[y.l]?x.r<y.r:blk[x.l]<blk[y.l];}
bool cmp2(N x,N y){return x.bh<y.bh;}
ll C(ll x){return x*(x-)/;}
ll gcd(ll a,ll b){return a%b==?b:gcd(b,a%b);}
void pop(int x){cnt[c[x]]--;ans-=cnt[c[x]];}//注意顺序
void push(int x){ans+=cnt[c[x]];cnt[c[x]]++;}
int main()
{
n=rd();m=rd();K=sqrt(n);
for(int i=;i<=n;i++)c[i]=rd(),blk[i]=(i-)/K+;
for(int i=;i<=m;i++)q[i].l=rd(),q[i].r=rd(),q[i].bh=i;
sort(q+,q+m+,cmp);
for(int i=,l=,r=;i<=m;i++)
{
while(l<q[i].l)pop(l),l++;
while(l>q[i].l)push(l-),l--;
while(r<q[i].r)push(r+),r++;
while(r>q[i].r)pop(r),r--;
q[i].a=ans;
q[i].b=C(r-l+);
ll k=gcd(q[i].a,q[i].b);//把分子放前面,万一分子是0
q[i].a/=k; q[i].b/=k;
}
sort(q+,q+m+,cmp2);
for(int i=;i<=m;i++)
printf("%lld/%lld\n",q[i].a,q[i].b);
return ;
}
bzoj2038 小Z的袜子(hose)——莫队算法的更多相关文章
- BZOJ2038: [2009国家集训队]小Z的袜子(hose) -- 莫队算法 ,,分块
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 3577 Solved: 1652[Subm ...
- [BZOJ2038] [2009国家集训队]小Z的袜子(hose) 莫队算法练习
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 10299 Solved: 4685[Sub ...
- BZOJ2038 小Z的袜子 (莫队算法)
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2038 专题练习: http://acm.hust.edu.cn/vjudge/conte ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 7687 Solved: 3516[Subm ...
- kyeremal-bzoj2038-[2009国家集训队]-小z的袜子(hose)-莫队算法
id=2038">bzoj2038-[2009国家集训队]-小z的袜子(hose) F.A.Qs Home Discuss ProblemSet Status Ranklist Con ...
- 【bzoj2038】[2009国家集训队]小Z的袜子(hose) 莫队算法
原文地址:http://www.cnblogs.com/GXZlegend/p/6803860.html 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终 ...
- [bzoj2038][2009国家集训队]小Z的袜子(hose)——莫队算法
Brief Description 给定一个序列,您需要处理m个询问,每个询问形如[l,r],您需要回答在区间[l,r]中任意选取两个数相同的概率. Algorithm Design 莫队算法入门题目 ...
- BZOJ2038: [2009国家集训队]小Z的袜子(hose) 莫队算法
要使用莫队算法前提 ,已知[l,r]的答案,要能在logn或者O(1)的时间得到[l+1,r],[l-1,r],[l,r-1],[l,r+1],适用于一类不修改的查询 优美的替代品——分块将n个数分成 ...
- Bzoj 2038---[2009国家集训队]小Z的袜子(hose) 莫队算法
题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色 ...
随机推荐
- PTA 01-复杂度2 Maximum Subsequence Sum (25分)
题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/663 5-1 Maximum Subsequence Sum (25分) Given ...
- ThinkPHP5 的入门学习
与Tp3.2相比,有一下的不同: (1)目录名称的改变: tp3.2的目录命名首字母皆为大写,例如:Application.Public.Controller.Model.View.ThinkPHP. ...
- hdu - 5007 Post Robot (水题)
http://acm.hdu.edu.cn/showproblem.php?pid=5007 #include<iostream> #include<stdio.h> #inc ...
- Java学习--反码 原码 补码简析
关于课上实验中对小数的处理中出现的问题涉及到原码,反码,补码的问题,所以在网上进行了一下搜索.在原码,反码,补码中的解释可得知,无论是哪一种码,能够表示的数的范围是-2^(位数-1)+1至2^(位数- ...
- HDTVI,HDCVI
HDTVI是海康的同轴高清标准,HDCVI是大华的同轴高清标准,二者互相不兼容.
- Visual studio 2017 中的Javascript智能提示与调试
1.智能提示 对于JS文件中的API,你若需要让那个JS文件中的方法能够在你写的那个JS文件中能够智能显示的话,直接把它拉进你的JS文件中就好了. 举个例子:你想 在你正在写的a.js文件中引用b.j ...
- "格式太旧或是类型库无效。 (异常来自 HRESULT:0x80028019 (TYPE_E_UNSUPFORMAT))"
错误提示内容: “System.Runtime.InteropServices.COMException (0x80028019): 格式太旧或是类型库无效. (异常来自 HRESULT:0x8002 ...
- cds.data:=dsp.data赋值有时会出现AV错误剖析
cds.data:=dsp.data赋值有时会出现AV错误剖析 如果QUERY没有查询到任何数据,cds.data:=dsp.data赋值会触发AV错误. 大家知道,DATASNAP有许多远程方法就是 ...
- Oracle 用户表空间查看、修改大小、设置自增长等
分类: Oracle 首先登入某个用户,查看某个用户在哪个表空间下: select username,default_tablespace from user_users; 查看该用户下所有的表: ...
- 代理服务器squid简介
Squid 是一个高性能.开源的代理缓存服务器和 Web 缓存进程,支持 FTP.Internet Gopher.HTTPS 和 SSL 等多种协议.它通过一个非阻塞的.I/O 事件驱动的单一进程处理 ...