[国家集训队]小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必须为最简分数。(详见样例)
输入输出样例
输入 #16 4 1 2 3 3 3 2 2 6 1 3 3 5 1 6输出 #12/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。
题目描述
作为一个生活散漫的人,小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必须为最简分数。(详见样例)
输入输出样例
输入 #16 4 1 2 3 3 3 2 2 6 1 3 3 5 1 6输出 #12/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。
摸你赛考出来了这题的在线版。
记录一下这道水体。
1 #include<bits/stdc++.h> 2 #define re register int 3 #define LL long long 4 #define maxn 50000+5 5 6 using namespace std; 7 int n,m; 8 int pos[maxn]; 9 int ci[maxn]; 10 LL ans,sum[maxn]; 11 inline int read(){ 12 int x=0,f=1; 13 char ch=getchar(); 14 while(!isdigit(ch)){ 15 if(ch=='-') f=-1; 16 ch=getchar(); 17 } 18 while(isdigit(ch)){ 19 x=(x<<3)+(x<<1)+ch-'0'; 20 ch=getchar(); 21 } 22 return x*f; 23 } 24 inline void write(int x){ 25 if(x<0){ 26 putchar('-'); 27 x=-x; 28 } 29 if(x>9) write(x/10); 30 putchar(x%10+'0'); 31 } 32 LL gcd(LL a,LL b) 33 { 34 if(a%b==0) return b; 35 else return gcd(b,a%b); 36 } 37 struct query{ 38 int l,r,id; 39 LL a,b; 40 }qu[maxn]; 41 bool cmp(const query &a,const query&b){ 42 return pos[a.l]==pos[b.l]?a.r<b.r:a.l<b.l; 43 } 44 bool cmp1(const query&a,const query&b) 45 { 46 return a.id<b.id; 47 } 48 void add(int p,int di) 49 { 50 ans-=sum[ci[p]]*sum[ci[p]]; 51 sum[ci[p]]+=di; 52 ans+=sum[ci[p]]*sum[ci[p]]; 53 } 54 void solve() 55 { 56 for(re i=1,curl=1,curr=0;i<=m;i++) 57 { 58 for(;curr<qu[i].r;curr++) 59 add(curr+1,1); 60 for(;curr>qu[i].r;curr--) 61 add(curr,-1); 62 for(;curl<qu[i].l;curl++) 63 add(curl,-1); 64 for(;curl>qu[i].l;curl--) 65 add(curl-1,1); 66 if(qu[i].l==qu[i].r){ 67 qu[i].a=0; 68 qu[i].b=1; 69 continue; 70 } 71 qu[i].a=ans-(qu[i].r-qu[i].l+1); 72 //取走后不放回原处 73 qu[i].b=(qu[i].r-qu[i].l+1)*1LL*(qu[i].r-qu[i].l); 74 LL gc=gcd(qu[i].a,qu[i].b); 75 qu[i].a/=gc; 76 qu[i].b/=gc; 77 } 78 79 } 80 int main() 81 { 82 std::ios::sync_with_stdio(false); 83 n=read(); 84 m=read(); 85 int cnt=sqrt(n); 86 for(re i=1;i<=n;i++) 87 { 88 ci[i]=read(); 89 pos[i]=(i-1)/cnt+1; 90 } 91 for(re i=1;i<=m;i++){ 92 qu[i].l=read(); 93 qu[i].r=read(); 94 qu[i].id=i; 95 } 96 sort(qu+1,qu+1+m,cmp); 97 solve(); 98 sort(qu+1,qu+1+m,cmp1); 99 for(re i=1;i<=m;i++) 100 cout<<qu[i].a<<"/"<<qu[i].b<<endl; 101 return 0; 102 }