BZOJ2038: [2009国家集训队]小Z的袜子(hose)
生活随笔
收集整理的這篇文章主要介紹了
BZOJ2038: [2009国家集训队]小Z的袜子(hose)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【傳送門:BZOJ2038】
簡要題意:
給出n只襪子,每只襪子都有顏色
有多個詢問,每次詢問一個區間L,R,求出在這個區間內選出兩只相同顏色襪子的概率,以最簡分數形式輸出(不用化成整數,如果概率為0,則輸出0/1)
題解:
接觸莫隊第一題
我們先假設當前要詢問的區間內第一種顏色的襪子有a只,第二種有b只......最后一種顏色的襪子有x只
那么我們輸出的答案應該是:$ans=\frac{\frac{a(a-1)}{2}+\frac{b(b-1)}{2}+...+\frac{x(x-1)}{2}}{\frac{(R-L+1)(R-L)}{2}}$
我們來化簡一下,得到:
$$ans=\frac{a(a-1)+b(b-1)+...+x(x-1)}{(R-L+1)(R-L)}$$
$$ans=\frac{a^2-a+b^2-b+...+x^2-x}{(R-L+1)(R-L)}$$
$$ans=\frac{a^2+b^2+...+x^2-(a+b+...+x)}{(R-L+1)(R-L)}$$
$$ans=\frac{a^2+b^2+...+x^2-(R-L+1)}{(R-L+1)(R-L)}$$
然后我們對它來進行莫隊求解
最后來膜一膜大米餅
參考代碼:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; typedef long long LL; LL gcd(LL a,LL b){if(a==0) return b;return gcd(b%a,a);} struct node {LL x,y;int id,l,r; }a[51000]; int bk[51000]; bool cmp1(node n1,node n2) {return bk[n1.l]==bk[n2.l]?n1.r<n2.r:bk[n1.l]<bk[n2.l]; } bool cmp2(node n1,node n2) {return n1.id<n2.id; } int col[51000]; LL sum[51000]; LL x; void update(int p,int c) {x-=sum[col[p]]*sum[col[p]];sum[col[p]]+=c;x+=sum[col[p]]*sum[col[p]]; } int main() {int n,m;scanf("%d%d",&n,&m);int block=int(sqrt(n));for(int i=1;i<=n;i++){scanf("%d",&col[i]);bk[i]=(i-1)/block+1;}for(int i=1;i<=m;i++){scanf("%d%d",&a[i].l,&a[i].r);a[i].id=i;}sort(a+1,a+m+1,cmp1);memset(sum,0,sizeof(sum));int l=1,r=0;x=0;for(int i=1;i<=m;i++){while(l<a[i].l){update(l,-1);l++;}while(l>a[i].l){update(l-1,1);l--;}while(r<a[i].r){update(r+1,1);r++;}while(r>a[i].r){update(r,-1);r--;}if(a[i].l==a[i].r){a[i].x=0;a[i].y=1;continue;}a[i].x=x-(r-l+1);a[i].y=LL(r-l+1)*LL(r-l);LL gd=gcd(a[i].x,a[i].y);a[i].x/=gd;a[i].y/=gd;}sort(a+1,a+m+1,cmp2);for(int i=1;i<=m;i++) printf("%lld/%lld\n",a[i].x,a[i].y);return 0; }?
轉載于:https://www.cnblogs.com/Never-mind/p/8073379.html
總結
以上是生活随笔為你收集整理的BZOJ2038: [2009国家集训队]小Z的袜子(hose)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js事件之event.preventDe
- 下一篇: STM32的备份寄存器测试