• [国家集训队][bzoj2038] 小Z的袜子 [莫队]


    题面:

    传送门

    思路:

    又是一道标准的莫队处理题目,但是这道题需要一点小改动:求个数变成了求概率

    我们思考:每次某种颜色从i个增加到i+1个,符合要求的情况多了多少?

    原来的总情况数是i*(i-1)/2,现在是i*(i+1)/2,实际上就是增加了i个!

    所以我们只要把对答案tot的更改变成加i即可

    莫队学习请戳这里:莫队

    Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define ll long long
     7 using namespace std;
     8 inline ll read(){
     9     ll re=0,flag=1;char ch=getchar();
    10     while(ch>'9'||ch<'0'){
    11         if(ch=='-') flag=-1;
    12         ch=getchar();
    13     }
    14     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    15     return re*flag;
    16 }
    17 ll n,m,cnt[100010],tot=0,x[50010],curl,curr,block;
    18 ll sqr[100010],ans[100010],bot[100010];
    19 struct query{
    20     ll l,r,i;
    21 }a[100010];
    22 bool cmp(query l,query r){
    23     if(l.l/block!=r.l/block) return (l.l/block)<(r.l/block);
    24     else return l.r<r.r;
    25 }
    26 void add(ll i){
    27     cnt[x[i]]++;tot+=sqr[cnt[x[i]]]-sqr[cnt[x[i]]-1];
    28     //cout<<"add "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<"
    ";
    29 }
    30 void erase(ll i){
    31     cnt[x[i]]--;tot+=sqr[cnt[x[i]]]-sqr[cnt[x[i]]+1];
    32     //cout<<"erase "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<"
    ";
    33 }
    34 void init(){
    35     for(ll i=1;i<=n;i++) sqr[i]=i*(i-1);
    36 }
    37 ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
    38 int main(){
    39     ll i;ll tmp,t1,t2;
    40     n=read();m=read();for(i=1;i<=n;i++) x[i]=read();block=sqrt(n);
    41     init();
    42     for(i=1;i<=m;i++) a[i].l=read(),a[i].r=read(),a[i].i=i;
    43     sort(a+1,a+m+1,cmp);curl=a[1].l;curr=a[1].r;
    44     for(i=a[1].l;i<=a[1].r;i++) add(i);
    45     ans[a[1].i]=tot;bot[a[1].i]=(a[1].r-a[1].l)*(a[1].r-a[1].l+1);
    46     if(a[1].l==a[1].r) bot[a[1].i]=1;
    47     for(i=2;i<=m;i++){
    48         while(curl<a[i].l) erase(curl++);
    49         while(curl>a[i].l) add(--curl);
    50         while(curr<a[i].r) add(++curr);
    51         while(curr>a[i].r) erase(curr--);
    52         ans[a[i].i]=tot;bot[a[i].i]=(a[i].r-a[i].l)*(a[i].r-a[i].l+1);
    53         if(a[i].l==a[i].r) bot[a[i].i]=1;
    54         //cout<<"now "<<tot<<" "<<a[i].l<<" "<<a[i].r<<"
    ";
    55     }
    56     for(i=1;i<=m;i++){
    57         if(ans[i]==0) printf("0/1
    ");
    58         else{
    59             tmp=gcd(bot[i],ans[i]);
    60             //cout<<"gcd "<<tmp<<" "<<ans[i]<<" "<<bot[i]<<"
    ";
    61             t1=ans[i]/tmp;t2=bot[i]/tmp;
    62             printf("%lld/%lld
    ",t1,t2);
    63         }
    64     } 
    65 }
  • 相关阅读:
    P1474 货币系统 Money Systems(完全背包求填充方案数)
    Codeforces 877C Slava and tanks(思维)
    883H
    Codeforces 873B
    POJ 1733 Parity game(带权并查集)
    POJ 2387 Til the Cows Come Home(dijkstra裸题)
    POJ 1984 Navigation Nightmare(二维带权并查集)
    POJ 2912 Rochambeau(种类并查集+枚举)
    POJ 1456 Supermarket(贪心+并查集)
    POJ 2492 A Bug's Life(带权并查集)
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8503756.html
Copyright © 2020-2023  润新知