P1494 [国家集训队]小Z的袜子

7 篇文章 0 订阅

给出m个查询[l,r],问[l,r]区间内随机拿出两双相同袜子的概率。

 

基础莫队题。对查询进行分块排序后,对l,r区间移来移去统计一下。

这里卡常数,比较器里面不能有除法。

int block_num;

struct query{
	int l,r,id;
	int block;
	bool operator<(const query &q) const{
		if(block != q.block) return l<q.l;
		return ((q.block)&1)? r < q.r : q.r<r;
	}
}q[N];

int len,id[N];
int c[N],num[N];
ll sum, tot[N],cnt[N];
bool cmp(query x,query y){
    if (id[x.l]==id[y.l]){
        if ((id[x.l]&1)==1) return x.r<y.r;
        else return x.r>y.r;	
    }
    else return id[x.l]<id[y.l];
}
ll gcd(ll a, ll b){
	return b?gcd(b,a%b):a;
}

ll ct(int num){
	return 1ll*num*(num-1);
}

void add(int idx){
	sum -= ct(num[idx]);
	sum += ct(++num[idx]);
}

void del(int idx){
	sum -= ct(num[idx]);
	sum += ct(--num[idx]);
}

int main(){
	int n,m;
	scanf("%d%d",&n,&m);
    len=sqrt(n);
	block_num = sqrt(n);
    fr(i,1,n+1) {
		scanf("%d",&c[i]);
		id[i]=i/len;
	}
	fr(i,0,m) {
		scanf("%d%d",&q[i].l,&q[i].r);
		q[i].id =i;
		q[i].block = q[i].l/block_num;
	}
	clr(num);
	sum = 0;
    sort(q,q+m);
	int l = 1, r = 0;
	fr(i,0,m){
		if(q[i].l == q[i].r){
			cnt[q[i].id] = 0;
			tot[q[i].id] = 1;
			continue;
		}
		while(l>q[i].l) add(c[--l]); 
		while(r<q[i].r) add(c[++r]);
		while(l<q[i].l) del(c[l++]);
		while(r>q[i].r) del(c[r--]);
		cnt[q[i].id] = sum;
		int len = r-l+1;
		tot[q[i].id] = ct(r-l+1);
	}
	
	fr(i,0,m){
		ll gd = gcd(cnt[i],tot[i]);
		printf("%lld/%lld\n",cnt[i]/gd, tot[i]/gd);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值