zoukankan      html  css  js  c++  java
  • ZROI十一集训Day2

    ZROI十一集训Day2

    比赛链接

    1.添

    开局几何懵逼题.
    内心:WOC,这什么毒瘤题?
    冷静分析( imes 1:)好像答案不会超过(3?)
    冷静分析( imes 2:)这好像是对的...
    冷静分析( imes 3:)完蛋,举出反例了.
    冷静分析( imes 4:)哦,这三线共点了,不合法.
    冷静分析( imes 5:)好像,分类讨论就好了,分有几种斜率,特判两种斜率时是否只有两条直线即可
    冷静分析( imes 6:)求斜率...精度问题怎么办...好像,用一个(pair)存最简分数形式就好了,用(map)
    冷静分析( imes 7:)噫好!我(A)了.

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <queue>
    #include <cmath>
    #include <ctime>
    #include <map>
    #include <set>
    #define MEM(x,y) memset ( x , y , sizeof ( x ) )
    #define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
    #define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
    #define pii pair < int , int >
    #define one first
    #define two second
    #define rint read<int>
    #define rll read<LL>
    #define LL long long
    #define pb push_back
    #define db double
    #define mid ( ( l + r ) >> 1 )
    
    using std::queue ;
    using std::set ;
    using std::pair ;
    using std::max ;
    using std::min ;
    using std::priority_queue ;
    using std::vector ;
    using std::swap ;
    using std::sort ;
    using std::unique ;
    using std::greater ;
    using std::map ;
    using std::__gcd ;
    
    template < class T >
        inline T read () {
            T x = 0 , f = 1 ; char ch = getchar () ;
            while ( ch < '0' || ch > '9' ) {
                if ( ch == '-' ) f = - 1 ;
                ch = getchar () ;
            }
            while ( ch >= '0' && ch <= '9' ) {
                x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
                ch = getchar () ;
            }
            return f * x ;
        }
    
    const int N = 1e6 + 100 ;
    
    struct Poi {
        int x , y ;
        friend Poi operator + (Poi a , Poi b) { return (Poi){ a.x + b.x , a.y + b.y } ; }
        friend Poi operator - (Poi a , Poi b) { return (Poi){ a.x - b.x , a.y - b.y } ; }
    } ;
    
    struct seg { Poi a , b , vec ; } p[N] ;
    
    map < pii , bool > mk ;
    int T , n , cnt , tot ;
    
    int main () {
        T = rint () ;
        while ( T -- ) {
            n = rint () ; cnt = 0 ; tot = 0 ; mk.clear () ;
            rep ( i , 1 , n ) {
                Poi u , v , vec ;
                u.x = rint () ; u.y = rint () ;
                v.x = rint () ; v.y = rint () ;
                int A = u.y - v.y , B =  u.x - v.x ;
                vec = v - u ; int d = __gcd ( A , B ) ;
                A /= d ; B /= d ;
                if ( mk[{A,B}] ) continue ;
                mk[{A,B}] = true ;
                p[++cnt] = (seg){ u , v , vec } ;
            }
            if ( cnt <= 1 ) puts ("0") ;
            else if ( cnt == 2 && n > 2 ) puts ("2") ;
            else if ( cnt == 2 && n <= 2 ) puts ("1") ;
            else puts ("3") ;
        }
        return 0 ;
    }
    

    2.罐装

    这题好难...是个贪心叭,看起来好像国王游戏.
    推一推昂(:)

    [egin{array}{c}{left(T-t-t_{i} ight) cdot p_{i}+left(T-t-t_{i}-t_{j} ight) cdot p_{j} geqleft(T-t-t_{j} ight) cdot p_{j}+left(T-t-t_{i}-t_{j} ight) cdot p_{i}} \ {t_{j} p_{i} geq t_{i} p_{j}} \ {cfrac{p_{i}}{t_{i}} geq cfrac{p_{j}}{t_{j}}}end{array} ]

    按照这个排序好了.(除法可能出现一些意想不到的问题,所以我们移项变为乘法排序.)
    噫好!我会了! 哎哎哎...这题怎么还带修啊...这咋做啊,让不让人活了啊.
    先暴力交上去算了(事实上比赛当场就是交了暴力...)

    冷静分析( imes 1:)修改好像只需要考虑贡献即可.
    考虑一个元素的修改,我们可以等价为删除一个数,再插入一个数.
    考虑删除的贡献:
    显然,对该元素的前缀并没有影响.只需要考虑对后面的影响和对自身的影响.
    首先,减去自己的贡献,我们发现它自己的贡献就是时间的前缀和( imes)自己的分数.
    减去即可.
    考虑对后缀的影响:
    后缀的所有元素的贡献从((T-sum_i)*p_i)变成了((T-sum_i+t_{pos})*p_i).
    其中(pos)是要删除的元素,(i)是当前考虑的元素.
    所以,贡献是加上分数的后缀和( imes)当前时间.

    插入一个元素的分析于此并无不同,只需贡献的符号反转即可.

    冷静分析( imes 2:)这东西显然平衡树可以维护.
    冷静分析( imes 3:)好像,离散化之后直接线段树也可做.
    冷静分析( imes 4:)分析个毛,线段树莽一棵.

    [2000 : years : later ]

    噫好,我(A)了.
    (Code:)

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <queue>
    #include <cmath>
    #include <ctime>
    #include <map>
    #include <set>
    #define MEM(x,y) memset ( x , y , sizeof ( x ) )
    #define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
    #define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
    #define pii pair < int , int >
    #define one first
    #define two second
    #define rint read<int>
    #define int long long
    #define pb push_back
    #define db double
    #define mid ( ( l + r ) >> 1 )
    
    using std::queue ;
    using std::set ;
    using std::pair ;
    using std::max ;
    using std::min ;
    using std::priority_queue ;
    using std::vector ;
    using std::swap ;
    using std::sort ;
    using std::unique ;
    using std::greater ;
    
    template < class T >
        inline T read () {
            T x = 0 , f = 1 ; char ch = getchar () ;
            while ( ch < '0' || ch > '9' ) {
                if ( ch == '-' ) f = - 1 ;
                ch = getchar () ;
            }
           while ( ch >= '0' && ch <= '9' ) {
                x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
                ch = getchar () ;
           }
           return f * x ;
    }
    
    const int N = 1e5 + 100 ;
    const pii e = { 0ll , 0ll } ;
    struct prob { int p , t , pos ; } v[N] , id[N<<1] , q[N] ;
    struct seg { pii data ; int ls , rs , left , right ; } t[N<<2] ;
    int n , m , T , pos[N<<1] , cnt = 1 , tot , ans ;
    
    inline pii operator + (pii a , pii b) { return { a.one + b.one , a.two + b.two } ; }
    
    inline void pushup (int rt) { t[rt].data = t[t[rt].ls].data + t[t[rt].rs].data ; return ; }
    
    inline void build (int rt , int l , int r) {
        t[rt].left = l ; t[rt].right = r ;
        if ( l == r ) { t[rt].data = e ; return ; }
        t[rt].ls = ++ cnt ; build ( t[rt].ls , l , mid ) ;
        t[rt].rs = ++ cnt ; build ( t[rt].rs , mid + 1 , r ) ;
        pushup ( rt ) ; return ;
    }
    
    inline void insert (int rt , int pos , pii key) {
        int l = t[rt].left , r = t[rt].right ;
        if ( l == r ) { t[rt].data = key ; return ; }
        if ( pos <= mid ) insert ( t[rt].ls , pos , key ) ;
        else insert ( t[rt].rs , pos , key ) ;
        pushup ( rt ) ; return ;
    }
    
    inline void remove (int rt , int pos) {
        int l = t[rt].left , r = t[rt].right ;
        if ( l == r ) { t[rt].data = e ; return ; }
        if ( pos <= mid ) remove ( t[rt].ls , pos ) ;
        else remove ( t[rt].rs , pos ) ;
        pushup ( rt ) ; return ;
    }
    
    inline pii query (int rt , int ll , int rr) {
        int l = t[rt].left , r = t[rt].right ;
        if ( ll == l && r == rr ) return t[rt].data ;
        if ( rr <= mid ) return query ( t[rt].ls , ll , rr ) ;
        else if ( ll > mid ) return query ( t[rt].rs , ll , rr ) ;
        else return query ( t[rt].ls , ll , mid ) + query ( t[rt].rs , mid + 1 , rr ) ;
    }
    
    inline bool cmp (prob a , prob b) { return a.p * b.t > a.t * b.p ; }
    
    signed main (int argc , char * argv[]) {
        n = rint () ; m = rint () ; T = rint () ;
        rep ( i , 1 , n ) { 
            v[i].p = rint () ; v[i].t = rint () ;
            v[i].pos = i ; id[++tot] = v[i] ;
        }
    
        rep ( i , 1 , m ) {
            q[i].pos = rint () ; q[i].p = rint () ; q[i].t = rint () ; ++ tot ;
            id[tot] = (prob){ q[i].p , q[i].t , tot } ;
        }
    
        sort ( id + 1 , id + tot + 1 , cmp ) ; rep ( i , 1 , tot ) pos[id[i].pos] = i ; build ( 1 , 1 , tot ) ;
    
        rep ( i , 1 , n ) insert ( 1 , pos[i] , { v[i].p , v[i].t } ) ; sort ( v + 1 , v + n + 1 , cmp ) ;
    
        int now = 0 ; rep ( i , 1 , n ) { now += v[i].t ; ans += ( T - now ) * v[i].p ; } printf ("%lld
    " , ans ) ;
    
        rep ( i , 1 , m ) {
            int cur = pos[q[i].pos] , tmp = query ( 1 , 1 , cur ).two ; ans -= id[cur].p * ( T - tmp ) ;
            if ( cur + 1 <= tot ) tmp = query ( 1 , cur + 1 , tot ).one ; else tmp = 0 ;
            ans += id[cur].t * tmp ; remove ( 1 , cur ) ;
    
            cur = pos[n+i] ; insert ( 1 , cur , { q[i].p , q[i].t } ) ;
            tmp = query ( 1 , 1 , cur ).two ; ans += q[i].p * ( T - tmp ) ;
            if ( cur + 1 <= tot ) tmp = query ( 1 , cur + 1 , tot ).one ; else tmp = 0 ;
            ans -= q[i].t * tmp ; pos[q[i].pos] = cur ; printf ("%lld
    " , ans ) ;
        }
        return 0 ;
    }
    

    3.三千米

    ⑧会.写的(Theta(T imes length imes log_2{max_{value}})).
    过了(30pts).
    (Code:)

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <queue>
    #include <cmath>
    #include <ctime>
    #include <map>
    #include <set>
    #define MEM(x,y) memset ( x , y , sizeof ( x ) )
    #define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
    #define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
    #define pii pair < int , int >
    #define one first
    #define two second
    #define rint read<int>
    #define rll read<LL>
    #define int long long
    #define pb push_back
    #define db double
    #define mid ( ( l + r ) >> 1 )
    
    using std::queue ;
    using std::set ;
    using std::pair ;
    using std::max ;
    using std::min ;
    using std::priority_queue ;
    using std::vector ;
    using std::swap ;
    using std::sort ;
    using std::unique ;
    using std::greater ;
    
    template < class T >
        inline T read () {
            T x = 0 , f = 1 ; char ch = getchar () ;
            while ( ch < '0' || ch > '9' ) {
                if ( ch == '-' ) f = - 1 ;
                ch = getchar () ;
            }
            while ( ch >= '0' && ch <= '9' ) {
                x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
                ch = getchar () ;
            }
            return f * x ;
        }
    
    int T , L , R , l , r ;
    
    inline bool check (int x) {
        int res = 1 ;
        while ( x ) {
            res *= ( x % 10 ) ;
            x /= 10 ;
        }
        return res >= l && res <= r ;
    }
    
    signed main() {
        T = rint () ;
        while ( T -- ) {
            L = rint () ; R = rint () ;
            l = rint () ; r = rint () ; int ans = 0 ;
            rep ( i , L , R ) if ( check ( i ) ) ++ ans ;
            printf ("%lld
    " , ans ) ;
        }
        return 0 ;
    }
    
    May you return with a young heart after years of fighting.
  • 相关阅读:
    python (八)迭代器、生成器、列表推导式
    python (七)装饰器
    HTML基础 (一)
    jQuery(一)
    JavaScript 练习(二)事件
    DOM节点(二)
    git操作顺序
    VUE练习(二)解决Bug
    前端环境VSCode
    JavaScript 基础基础最基础
  • 原文地址:https://www.cnblogs.com/Equinox-Flower/p/11631936.html
Copyright © 2011-2022 走看看