• 【BZOJ2038】小Z的袜子【莫队】


    题意

      给出包含n个数字的序列,和m个查询。每次查询问区间[l,r]中挑选出两个数字,大小相同的概率为多少。

    分析

      莫队的入门题吧。代码是非常好写,关键是时间复杂度的证明。O(n*sqrt(n))。我还有点迷糊,等我再做几个题再说···

      

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 typedef long long LL;
     9 const int maxn=50000+100;
    10 int val[maxn],belong[maxn],f[maxn];
    11 int n,m,cnt,block;
    12 LL gcd(LL a,LL b){
    13     if(!b)return a;
    14     return gcd(b,a%b);
    15 }
    16 
    17 struct Node{
    18     int L,R,id;
    19     bool operator<(const Node& rhs)const{
    20         return belong[L]<belong[rhs.L]||(belong[L]==belong[rhs.L]&&R<rhs.R);
    21     }
    22     LL a,b;
    23     void solve(){
    24         LL r=gcd(a,b);
    25         a/=r,b/=r;
    26     }
    27 }ask[maxn];
    28 int cmp(Node a,Node b){
    29     return a.id<b.id;
    30 }
    31 LL ans;
    32 void update(int p,int addv){
    33     ans=ans+2*addv*f[val[p]]+1;
    34     f[val[p]]+=addv;
    35 }
    36 
    37 int main(){
    38     scanf("%d%d",&n,&m);
    39     memset(f,0,sizeof(f));
    40     for(int i=1;i<=n;i++)
    41         scanf("%d",&val[i]);
    42     block=sqrt(n);
    43     cnt=n/block;
    44     if(n%block)cnt++;
    45     for(int i=1;i<=n;i++){
    46         belong[i]=(i-1)/block+1;
    47     }
    48     for(int i=1;i<=m;i++){
    49         scanf("%d%d",&ask[i].L,&ask[i].R);
    50         ask[i].id=i;
    51     }
    52 
    53     sort(ask+1,ask+1+m);
    54     ans=0;
    55     int l=1,r=0;
    56     for(int i=1;i<=m;i++){
    57         if(r<ask[i].R){
    58             for(r=r+1;r<ask[i].R;r++){
    59                 update(r,1);
    60             }
    61             update(r,1);
    62         }
    63         if(l>ask[i].L){
    64             for(l=l-1;l>ask[i].L;l--){
    65                 update(l,1);
    66             }
    67             update(l,1);
    68         }
    69         if(r>ask[i].R){
    70             for(;r>ask[i].R;r--){
    71                 update(r,-1);
    72             }
    73         }
    74         if(l<ask[i].L){
    75             for(;l<ask[i].L;l++){
    76                 update(l,-1);
    77             }
    78         }
    79         if(ask[i].L==ask[i].R){
    80             ask[i].a=0,ask[i].b=1;
    81             continue;
    82         }
    83         ask[i].a=ans-(ask[i].R-ask[i].L+1),ask[i].b=(LL)(ask[i].R-ask[i].L+1)*(ask[i].R-ask[i].L);
    84         ask[i].solve();
    85     }
    86     sort(ask+1,ask+1+m,cmp);
    87     for(int i=1;i<=m;i++){
    88         printf("%lld/%lld
    ",ask[i].a,ask[i].b);
    89     }
    90 return 0;
    91 }
    View Code
  • 相关阅读:
    戴尔英语09年互联网络投放策略规划书
    haproxy相关
    邮送广告
    python和rails交互应用
    ubuntu搭建邮件服务器
    waitr自动化测试
    ruby写爬虫
    free git svn repositories
    网站开发外包遇到的问题
    电影推荐
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9581034.html
Copyright © 2020-2023  润新知