小Z的袜子
题目链接:https://www.luogu.com.cn/problem/P1494
题意:
求在区间[l,r]上取得两个相同颜色的袜子的概率
思路:
莫队,注意开longlong以及最后直接用最大公约数gcd约分
int n,m;
int a[maxn];
int cnt[maxn];
struct node{
int l,r,id;
}q[maxn];
int k;
bool cmp(node a,node b){
if(a.l/k!=b.l/k)return a.l/k < b.l/k;
if((a.l/k)&1)return a.r<b.r;else return a.r>b.r;
}
int res;
int countt=0;
void add(int x){
// if(!cnt[a[x]])res++;
cnt[a[x]]++;
if(cnt[a[x]]==2){
res+= cnt[a[x]]*(cnt[a[x]]-1);
}else if(cnt[a[x]]>2){
res+= (cnt[a[x]]*(cnt[a[x]]-1)-(cnt[a[x]]-1)*(cnt[a[x]]-2));
}
// debug(cnt[a[x]]);
}
void del(int x){
cnt[a[x]]--;
if(cnt[a[x]]==1)res-=2;
else if(cnt[a[x]]>=2){
res-=(cnt[a[x]]+1)*(cnt[a[x]]);
res+=(cnt[a[x]])*(cnt[a[x]]-1);
}
// if(!cnt[x])res--;
}
void solve(){
cin>>n>>m;
k=n/sqrt(m*2/3);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++){
int l,r;cin>>l>>r;
q[i]=node{l,r,i};
}
sort(q+1,q+1+m,cmp);
vector<pii>ans(m+2);
for(int i=1,r=0,l=1;i<=m;i++){
countt=q[i].r-q[i].l+1;
// debug(countt);
// debug(q[i].l);
// debug(q[i].r);
if(countt==1){
ans[q[i].id].fi=0;
ans[q[i].id].se=1;
continue;
}
while(l>q[i].l)add(--l);
while(l<q[i].l)del(l++);
while(r<q[i].r)add(++r);
while(r>q[i].r)del(r--);
ans[q[i].id].fi=res;
ans[q[i].id].se=countt;
}
for(int i=1;i<=m;i++){
// debug(ans[i].fi);
if(ans[i].fi==0){
cout<<ans[i].fi<<'/'<<1<<endl;continue;
}
int p=ans[i].se*(ans[i].se-1);
int sk=__gcd(ans[i].fi,p);
ans[i].fi/=sk;p/=sk;
cout<<ans[i].fi<<'/';
cout<<p<<endl;
}
}

浙公网安备 33010602011771号