莫队+分块
来源:互联网 发布:微信 for mac 2.0 编辑:程序博客网 时间:2024/06/05 16:29
这个题是bzoj-2038
题目链接:
题意:给出n个数字,m次询问,每次询问在区间\([l_i,r_i]\)之间任选两个数字相等的概率是多少。(n,q<=50000)
思路:这道题是比较模板的莫队分块了,对于一个区间询问[L,R],我们要求的ans是
∑C(f[i],2)/C(r-l+1,2)
然后有:∑(f[i]^2-f[i])/((r-l+1)*(r-l))
其中那么我们现在求出各个询问区间中
注意:
1.当一种颜色数量ci增加1时,我们可以看出
*f[i]+(f[i]+1)2
2.极限数据50000*50000如果不用longlong会教你做人←_←
莫队算法可用于解决一类可离线且在得到区间\([l,r]\)的答案后,能在\(O(1)\)或\(O(\log_2{n})\)得到区间\([l,r+1]\)或\([l-1,r]\)的答案的问题,这个区间是m个不变的区间,
莫队的分块写法是很好的一个东西,持续学习中
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <set>#include <map>#include <stack>#include <vector>#include <queue>#define ri(n) scanf("%d",&n)#define oi(n) printf("%d\n",n)#define rl(n) scanf("%lld",&n)#define ol(n) printf("%lld\n",n)#define rep(i,l,r) for(i=l;i<=r;i++)#define rep1(i,l,r) for(i=l;i<r;i++)using namespace std;typedef long long ll;const int inf=0x3f3f3f3f;const int maxn=50000+500;const int epg=10-8;int n,m;int len;ll ans;int bb[maxn],a[maxn],f[maxn];ll gcd(ll a,ll b){ if(!b) return a; return gcd(b,a%b);}struct node{ int l,r,id; ll a,b; bool operator<(const node &x)const { return bb[l]<bb[x.l]||(bb[l]==bb[x.l]&&r<x.r); } void _gcd() { ll k=gcd(a,b); a/=k; b/=k; }}q[maxn];/*void modit(int pos,int add){ ans+=2*add*f[a[pos]]+1; f[a[pos]]+=add;}*/bool cmp(node x,node y){ return x.id<y.id;}void solve(){ int l=1,r=0; ans=0; for(int i=1;i<=m;i++) { if(q[i].l<l) { for(l=l-1;q[i].l<l;l--) { ans-=f[a[l]]*f[a[l]]; f[a[l]]++; ans+=f[a[l]]*f[a[l]]; } ans-=f[a[l]]*f[a[l]]; f[a[l]]++; ans+=f[a[l]]*f[a[l]]; //modit(l,1); //modit(l,1); } if(l<q[i].l) { for(;l<q[i].l;l++) { ans-=f[a[l]]*f[a[l]]; f[a[l]]--; ans+=f[a[l]]*f[a[l]]; } //modit(l,-1); } if(q[i].r<r) { for(;q[i].r<r;r--) { ans-=f[a[r]]*f[a[r]]; f[a[r]]--; ans+=f[a[r]]*f[a[r]]; } //modit(r,-1); } if(r<q[i].r) { for(r=r+1;r<q[i].r;r++) { ans-=f[a[r]]*f[a[r]]; f[a[r]]++; ans+=f[a[r]]*f[a[r]]; } ans-=f[a[r]]*f[a[r]]; f[a[r]]++; ans+=f[a[r]]*f[a[r]]; //modit(r,1); //modit(r,1); } if(q[i].l==q[i].r) { q[i].a=0; q[i].b=1; continue; } q[i].a=ans-(q[i].r-q[i].l+1); q[i].b=ll((q[i].r-q[i].l+1)*(q[i].r-q[i].l)); q[i]._gcd(); //printf("%lld/%lld\n",q[i].a,q[i].b); } sort(q+1,q+1+m,cmp); for(int i=1;i<=m;i++) printf("%lld/%lld\n",q[i].a,q[i].b);}int main(){ while(scanf("%d%d",&n,&m)==2) { memset(bb,0,sizeof(bb)); memset(f,0,sizeof(f)); len=sqrt(n); for(int i=1;i<=n;i++) bb[i]=(i-1)/len+1; for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) { scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; } sort(q+1,q+1+m); solve(); } return 0;}/*6 41 2 3 3 3 22 61 33 51 6*/
阅读全文
0 0
- 莫队+分块
- 【bzoj3585】mex 莫队+分块
- [莫队] [分块] [BZOJ3585] mex
- bzoj3809 -- 莫队+分块
- 分块。。
- 分块
- 分块
- 分块
- 分块
- 分块
- 分块
- 【分块】
- bzoj 3809(莫队+分块求和)
- BZOJ3236: [Ahoi2013]作业 莫队+分块
- bzoj 3809(莫队+分块)
- 【NOIP模板】 莫队(分块)
- bzoj 3236(莫队+分块)
- 莫队+分块+树状数组 【Ahoi2013】 作业 bzoj3236
- laravel5.2 生成缩略图
- 错误接受率 (FAR), 错误拒绝率(FRR), 等错误率(EER)
- YTU.3179: 小黄车ofo
- WorkerMan学习篇:二
- 如何顺利地将Docker安装至Win7(x64)?
- 莫队+分块
- php-fpm监听socket类型-解决Connection refused
- 5.1
- Reflection2017.11.8
- MVP注册登录+OkHttp网络请求+展示数据
- 小波变换
- 蓝桥杯 算法训练 P1103
- Java SE Collection
- luogu P1101 单词方阵【dfs】