[国家集训队]小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。

题目描述

作为一个生活散漫的人,小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。

        摸你赛考出来了这题的在线版。

        记录一下这道水体。

  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 }
View Code

 

posted @ 2019-10-04 20:13  3200Phaethon  阅读(177)  评论(1编辑  收藏  举报