• [题解] 2038: [2009国家集训队]小Z的袜子(hose)


    莫队,卡常数


    题目地址

    • 思路

      • ( ext{Vis[i]})为元素( ext{i})在区间( ext{[L,R]})的出现次数

      • 考虑区间( ext{[L,R]})和元素( ext{i}),首次取出的概率为(frac{Vis[i]}{R-L+1}),再次取出的概率是(frac{Vis[i]-1}{R-L})

      • 对于区间( ext{[L,R]}),答案为(sum_{i=1}^{N}{frac{Vis[i](Vis[i]-1)}{(R-L)*(R-L+1)}})

      • 这样,每次给变( ext{[L,R]}),分子的变化可以通过对前、后两项的值做差得到:

        • 设X=Vis[i],有:

        [(X+1)X-(X)(X-1)=2X ]

      • 莫队这样修改即可。

    • Code

      • /**************************************************************
            Problem: 2038
            User: Bj2002
            Language: C++
            Result: Accepted
            Time:11036 ms
            Memory:2584 kb
        ****************************************************************/
         
        #include <stdio.h>
        #include <string.h>
        #include <algorithm>
        #define GC getchar()
        #define Clean(X,K) memset(X,K,sizeof(X))
        using namespace std ;
        int Qread () {
            int X = 0 ;
            char C = GC ;
            while (C > '9' || C < '0') C = GC ;
            while (C >='0' && C <='9') {
                X = X * 10 + C - '0' ;
                C = GC ;
            }
            return X ;
        }
        long long GCD(long long M, long long N) {
            while (N != 0) {
                long long T = M % N;
                M = N;
                N = T;
            }
            return M;
        }
        const int Maxn = 50005 ;
        int N , M , A[Maxn] , Vis[Maxn]  ;
        long long Ans[Maxn] , Sum[Maxn];
        struct Node {
            int Left , Right  , Place;
        };
        Node Q[Maxn] ;
        bool Cmp (const Node &X , const Node &Y) {
            if (X.Left != Y.Left ) return X.Left < Y.Left ;
            if (X.Left & 1) return X.Right < Y.Right ;
            else return X.Right > Y.Right ;
        }
        bool Cmp2 (const Node &X , const Node &Y) {
            return X.Place < Y.Place ;
        }
        void Qwrite(int X) {
            if(X > 9) Qwrite(X / 10);
            putchar(X % 10 + '0');
        }
         
        int main () {
        //  freopen ("P1494.in" , "r" , stdin) ;
        //  freopen ("P1494.out", "w" , stdout) ;
            N = Qread () , M = Qread ();
            for (int i = 1 ; i <= N; ++ i) A[i] = Qread () ;
            for (int i = 1 ; i <= M; ++ i) Q[i].Left = Qread () , Q[i].Right = Qread () , Q[i].Place = i ;;
            sort (Q + 1 , Q + 1 + M , Cmp) ;
            Clean (Vis , 0) ;
            int L , R ;
            long long Now = 0 ;
            L = R = Q[1].Left ;
            Vis[A[L]] = 1 ;
            for (int i = 1 ; i <= M; ++ i) {
                while (L < Q[i].Left ) {
                    -- Vis[A[L]] ;
                    Now -= (Vis[A[L]] << 1) ;
                    ++ L ;
                }
        //      cout << L <<' '<<R <<' '<<Now<<endl;
                while (R < Q[i].Right ) {
                    ++ R ;
                    Now += (Vis[A[R]] << 1) ;
                    ++ Vis[A[R]] ;
                }
        //      cout << L <<' '<<R <<' '<<Now<<endl;
                while (R > Q[i].Right ) {
                    -- Vis[A[R]] ;
                    Now -= (Vis[A[R]] << 1) ;
                    -- R ;
                }
        //      cout << L <<' '<<R <<' '<<Now<<endl;
                Ans[Q[i].Place] = Now , Sum[Q[i].Place ] = ((long long)Q[i].Right - Q[i].Left ) * (Q[i].Right - Q[i].Left + 1) ;
            }
            std :: sort (Q + 1 , Q + 1 + M , Cmp2) ;
            for (int i = 1 ; i <= M; ++ i) {
                if (Q[i].Left == Q[i].Right ) printf ("0/1
        ") ;
                else {
                    int K = GCD (Ans[i] , Sum[i]) ;
                    Ans[i] /= K , Sum[i] /= K ;
                    printf ("%lld/%lld
        " , Ans[i] , Sum[i]) ;
                }
            }
            fclose (stdin) , fclose (stdout) ;
            return 0 ;
        }
        

    Thanks!

  • 相关阅读:
    bootstrap添加模态窗后,再弹出消息提示框后,原先的滚动条消失
    改变input[type=file]的默认样式
    javascript判断访问终端,手机端自动跳转
    sublime安装插件autoprefixer
    android 自动化压力测试-monkey 1 实践
    python 网络编程-TCP/UDP
    python 正则表达式
    Python 读写excel数据
    Python 删除列表中的重复数据
    Python python 基本语法
  • 原文地址:https://www.cnblogs.com/bj2002/p/10791896.html
Copyright © 2020-2023  润新知