小z的袜子
傳送門
題目描述
作為一個生活散漫的人,小Z每天早上都要耗費很久從一堆五顏六色的襪子中找出一雙來穿。終于有一天,小Z再也無法忍受這惱人的找襪子過程,于是他決定聽天由命……
具體來說,小Z把這N只襪子從1到N編號,然后從編號L到R(L 盡管小Z并不在意兩只襪子是不是完整的一雙,甚至不在意兩只襪子是否一左一右,他卻很在意襪子的顏色,畢竟穿兩只不同色的襪子會很尷尬。
你的任務便是告訴小Z,他有多大的概率抽到兩只顏色相同的襪子。當然,小Z希望這個概率盡量高,所以他可能會詢問多個(L,R)以方便自己選擇。
然而數據中有L=R的情況,請特判這種情況,輸出0/1。
輸入輸出格式
輸入格式:輸入文件第一行包含兩個正整數N和M。N為襪子的數量,M為小Z所提的詢問的數量。接下來一行包含N個正整數Ci,其中Ci表示第i只襪子的顏色,相同的顏色用相同的數字表示。再接下來M行,每行兩個正整數L,R表示一個詢問。
輸出格式:包含M行,對于每個詢問在一行中輸出分數A/B表示從該詢問的區間[L,R]中隨機抽出兩只襪子顏色相同的概率。若該概率為0則輸出0/1,否則輸出的A/B必須為最簡分數。(詳見樣例)
輸入輸出樣例
輸入樣例#1:? 6 4 1 2 3 3 3 2 2 6 1 3 3 5 1 6 輸出樣例#1:? 2/5 0/1 1/1 4/15說明
30%的數據中 N,M ≤ 5000;
60%的數據中 N,M ≤ 25000;
100%的數據中 N,M ≤ 50000,1 ≤ L < R ≤ N,Ci ≤ N。
分析
裸的莫隊算法,用tot數組記錄每一顏色的總數,不難算出:每增加一個某顏色襪子,配成一對同色襪子的情況增加(tot-1),減少時的情況相同。
特別注意!!!:1ll要放在數的前面乘
代碼
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int n,m,a[60000],belong[60000];
long long ans[60000];
struct node{
?? ?? int le,ri,no;
?? ?? long long num;
}q[60000];
int L=1,R;
long long Ans;
int block,sum;
long long tot[60000];
long long S[60000];
bool cmp(const node &x,const node &y){
?? ?? if(belong[x.le]==belong[y.le])return x.ri<y.ri;
?? ?? return belong[x.le]<belong[y.le];
}
void add(int x){
?? ?? tot[a[x]]++;
?? ?? Ans+=tot[a[x]]-1;
}
void del(int x){
?? ?? tot[a[x]]--;
?? ?? Ans-=tot[a[x]];
}
long long gcd(long long a,long long b){
?? ?? if((a%b)==0)
?? ???? return b;
?? ?? return gcd(b,a%b);
}
int main()
{???? int i,j,k;
????? cin>>n>>m;
????? block=sqrt(n);
????? sum=((n%block)==0?(n/block):(n/block+1));
????? for(i=1;i<=n;i++){
???? ??? ?scanf("%d",&a[i]);
???? ??? ?belong[i]=(i-1)/block+1;
????? }
????? for(i=1;i<=m;i++){
???? ??? ?scanf("%d%d",&q[i].le,&q[i].ri);
???? ??? ?q[i].no=i;
???? ??? ?q[i].num=1ll*(q[i].ri-q[i].le+1)*(q[i].ri-q[i].le)/2;
????? }
????? sort(q+1,q+m+1,cmp);
????? for(i=1;i<=m;i++){
???? ??? ?while(L<q[i].le){
???? ??? ??? ?del(L);
???? ??? ??? ?L++;
???? ??? ?}
???? ??? ?while(L>q[i].le){
???? ??? ??? ?L--;
???? ??? ??? ?add(L);
???? ??? ?}
???? ??? ?while(R>q[i].ri){
???? ??? ??? ?del(R);
???? ??? ??? ?R--;
???? ??? ?}
???? ??? ?while(R<q[i].ri){
???? ??? ??? ?R++;
???? ??? ??? ?add(R);
???? ??? ?}
???? ??? ?ans[q[i].no]=Ans;
???? ??? ?S[q[i].no]=q[i].num;
???? ??? ?if(q[i].le==q[i].ri)
???? ??? ?? ans[q[i].no]=0,
???? ??? ?? S[q[i].no]=1;
????? }
????? for(i=1;i<=m;i++){
???? ??? ?long long x=gcd(ans[i],S[i]);
???? ??? ?printf("%lld/%lld\n",ans[i]/x,S[i]/x);
????? }
?? ?? return 0;
}
轉載于:https://www.cnblogs.com/yzxverygood/p/8353030.html
總結
- 上一篇: Elasticsearch 快速入门
- 下一篇: 【Storm篇】--Storm并发机制