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

给定序列a[1]~a[n],a[i]表示i的颜色,多次询问区间L~R中选出两个位置颜色相同的概率

N,Q<=50000.

若我们已知L~R区间出现的颜色为c1~ck,次数cnt1~cntk
概率表达式?




若我们已知[L,R]的信息(cnt,P),我们可以O(1)将它更新为[L+1,R]/[L-1,R]/[L,R-1]/[L,R+1].此即为莫队算法。

我们将询问以[(l-1)/sqrt(N)]为第一关键字,R为第二关键字排序,我们暴力求出第一个询问的答案,然后对于以后的询问答案由之前的询问进行更新
时间复杂度?
右端点O(N*sqrt(N))
左端点O(N)
总时间复杂度O(N*sqrt(N))

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> 
#define ll long long
#define N 50000
using namespace std;
int n,m,A[N+5],block;
ll ans=0,f[N];
struct query{
	int l,r,id,block;
}data[N+5];
struct ANs{
	ll a,b;
}ANS[N];
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
bool cmp(query x,query y){
	return x.block==y.block? x.r<y.r:x.block<y.block;
}
void update(int x,int op){
	ans-=f[A[x]]*(f[A[x]]-1);
	f[A[x]]+=op;
	ans+=f[A[x]]*(f[A[x]]-1);
}
inline ll gcd(ll x,ll y){
	return y==0?x:gcd(y,x%y);
}
int main(){
	freopen("a.in","r",stdin);
	n=read();m=read();block=sqrt(n);
	for(int i=1;i<=n;++i) A[i]=read();
	for(int i=1;i<=m;++i){
		data[i].l=read();data[i].r=read();data[i].id=i;
		data[i].block=(data[i].l-1)/block;
	}
	sort(data+1,data+m+1,cmp);
	int l=1,r=0;//l一定要从1开始,r从0开始 
	ll a=0,b=0;
	for(int i=1;i<=m;++i){
		for(;l>data[i].l;--l) update(l-1,1);
		for(;l<data[i].l;++l) update(l,-1);
		for(;r<data[i].r;++r) update(r+1,1);
		for(;r>data[i].r;--r) update(r,-1);
		if(data[i].l==data[i].r){
			ANS[data[i].id].a=0;
			ANS[data[i].id].b=1;continue;
		}
		a=ans;b=(ll)(data[i].r-data[i].l+1)*(data[i].r-data[i].l);
		ll k=gcd(a,b);
		ANS[data[i].id].a=a/k;ANS[data[i].id].b=b/k;
	}
	for(int i=1;i<=m;++i)
		printf("%lld/%lld\n",ANS[i].a,ANS[i].b);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值