• 2019nc#7


    题号标题已通过代码题解/讨论通过率团队的状态
    A String 点击查看 进入讨论 566/3539  通过
    B Irreducible Polynomial 点击查看 规律 730/2290 未通过
    C Governing sand 点击查看 进入讨论 388/2088  通过
    D Number 点击查看 进入讨论 959/1469  通过
    E Find the median 点击查看 离散化 88/985 OK
    F Energy stones 点击查看 BIT 16/132 未通过
    G Make Shan Happy 点击查看 进入讨论 3/29 未通过
    H Pair 点击查看 数位DP 93/245 OK
    I Chessboard 点击查看 进入讨论 17/83 未通过
    J A+B problem 点击查看 进入讨论 1024/1844  通过
    K Function 点击查看 进入讨论 8/49 未通过

    E-Find the median

    题意

    n次操作,($n le 400000$),每次给出$L_i, R_i$向集合中插入,让你把$[L_i, L_i+1, L_i+2, ... , R_i]$ 插入到集合中,同时输出集合的中位数。

    集合一开始为空,($1 le L_i, R[i] le 1e9$)

    思路

    空间有限,所以不可以把两个端点间的一段单独拿出来当成一个点

    动态开点也被卡了空间

    具体思路还是离散化,我们可以中间的点和左端点看成一个点

    把原来对闭区间的操作改为对左闭右开区间的操作

    就是把原来的$[L_i, R_i]$ 更改为 $[L_i, R_i + 1)$

    // #pragma GCC optimize(2)
    //  #pragma GCC optimize(3)
    //  #pragma GCC optimize(4)
    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    // #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    using namespace std;
    #define pb push_back
    #define fi first
    #define se second
    #define debug(x) cerr<<#x << " := " << x << endl;
    #define bug cerr<<"-----------------------"<<endl;
    #define FOR(a, b, c) for(int a = b; a <= c; ++ a)
     
    typedef long long ll;
    typedef long double ld;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
     
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9+7;
     
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
     
    /**********showtime************/
                const int big = 1e9;
                const int maxn = 400005;
                int X[maxn],Y[maxn];
                int L[maxn], R[maxn];
                int a1,b1,c1,m1;
                int a2,b2,c2,m2;
                struct node{
                    int cnt;
                    ll sum;
                    int lazy;
                    int len;
                } tree[maxn * 8];
                //离散化
                vector<int>vec;
                int getid(int x) {
                    return lower_bound(vec.begin(), vec.end(), x) - vec.begin() + 1;
                }
                //
    
                void pushdown(int le,int ri,int rt) {
                    tree[rt<<1].cnt += tree[rt].lazy;
                    tree[rt<<1|1].cnt += tree[rt].lazy;
                    tree[rt<<1].lazy += tree[rt].lazy;
                    tree[rt<<1|1].lazy += tree[rt].lazy;
                    int mid = (le + ri) >> 1;
    
                    tree[rt<<1].sum +=  1ll*tree[rt].lazy * (vec[mid] - vec[le-1]);
                    tree[rt<<1|1].sum +=  1ll*tree[rt].lazy *(vec[ri] - vec[mid]);
                    tree[rt].lazy = 0;
                }
    
                
                void update(int L, int R, int le, int ri, int rt) {
                    if(le >= L && ri <= R) {
                        tree[rt].lazy++;
                        tree[rt].cnt++;
                        //因为每个节点表示【le实际值,ri实际值)的长度。
                        tree[rt].sum += 1ll*(vec[ri] - vec[le - 1]);
                        return;
                    }
                    int mid = (le + ri) >> 1;
                    if(tree[rt].lazy) pushdown(le,ri,rt);
                    if(mid >= L) {
                        update(L, R, le, mid, rt<<1);
                    }
                    if(mid < R) {
                        update(L, R, mid+1, ri, rt<<1|1);
                    }
                    tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
                }
    
                int query(ll tot, int le, int ri, int rt) {
                    if(le == ri) {
    
                        int cnt = tree[rt].cnt, res;
                        int lbound = vec[le-1];
                        if(tot % cnt == 0) {
                            res = lbound + tot / cnt - 1;
                        }
                        else
                            res = lbound + tot / cnt;
                        return res;
    
                    }
     
                    int mid = (le + ri) >> 1;
                    if(tree[rt].lazy) pushdown(le,ri,rt);
     
                    ll lsum = tree[rt<<1].sum;
                    if(lsum >= tot) return query(tot,le, mid, rt<<1);
                    else return query(tot - lsum, mid+1, ri, rt<<1|1);
                }
    int main(){
     
                int n;
                scanf("%d", &n);
                scanf("%d%d%d%d%d%d", &X[1], &X[2], &a1, &b1, &c1, &m1);
                scanf("%d%d%d%d%d%d", &Y[1], &Y[2], &a2, &b2, &c2, &m2);
                
                L[1] = min(X[1], Y[1]) + 1;
                R[1] = max(X[1], Y[1]) + 1;
                L[2] = min(X[2], Y[2]) + 1;
                R[2] = max(X[2], Y[2]) + 1;
                //因为我后面操作的是左闭右开区间,所以这里右端点++。
                R[1] ++; R[2] ++;
                vec.pb(L[1]);vec.pb(R[1] );
                vec.pb(L[2]);vec.pb(R[2]);
                for(int i=3; i<=n; i++) {
                    X[i] = (1ll*a1 * X[i-1] + 1ll*b1 * X[i-2] + c1 )% m1;
                    Y[i] = (1ll*a2 * Y[i-1] + 1ll*b2 * Y[i-2] + c2 )% m2;
                    L[i] = min(X[i], Y[i]) + 1;
                    R[i] = max(X[i], Y[i]) + 1;
                    R[i] ++;
                    vec.pb(L[i]);   vec.pb(R[i]);
                }
                sort(vec.begin(), vec.end());
                vec.erase(unique(vec.begin(), vec.end()), vec.end());
                for(int i=1; i<=n; i++) {
                    L[i] = getid(L[i]);
                    R[i] = getid(R[i]);
                }
                
                int tot = vec.size();
    
                ll all = 0;
    
                for(int i=1; i<=n; i++) {
                    
                    update(L[i], R[i] - 1, 1, tot, 1);
    
                    all += 1ll*(vec[R[i]-1] - vec[L[i] - 1]);
                    
                    printf("%d
    ", query((all + 1)/2, 1, tot, 1));
                }
                return 0;
    }
    View Code

    H Pair

    题意

    给定A,B,C($A le 1e9, B le 1e9, C le 1e9$),求满足

    $$ (x & y) > C $$

    $$ (x oplus y)  < C$$

    的<x, y>对数。其中

    $ 1 le x le A, 1 le y le B$

    思路

    数位DP,自己code了好久

    /*
    * @Author: chenkexing
    * @Date:   2019-08-09 23:58:00
    * @Last Modified by:   chenkexing
    * @Last Modified time: 2019-08-10 22:19:16
    * @Link https://ac.nowcoder.com/acm/contest/887/H
    */
    // #pragma GCC optimize(2)
    //  #pragma GCC optimize(3)
    //  #pragma GCC optimize(4)
    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    // #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    using namespace std;
    #define pb push_back
    #define fi first
    #define se second
    #define debug(x) cerr<<#x << " := " << x << endl;
    #define bug cerr<<"-----------------------"<<endl;
    #define FOR(a, b, c) for(int a = b; a <= c; ++ a)
      
    typedef long long ll;
    typedef long double ld;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
      
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9+7;
      
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
      
    /**********showtime************/
    ll dp[35][2][2][2][2][3][3];
    //dp[len][limit1][limit2][ok1][ok2]
    //由于两个数要大于0,所以多加上ok1,ok2.
    //f1 &的, f2 ^的 // == 2 表示不行了
    int shuA[35],shuB[35],shuC[35];
    ll dfs(int len, int limit1, int limit2, int ok1, int ok2, int f1, int f2){
        if(f1 == 2 && f2 == 2) return 0;
        if(dp[len][limit1][limit2][ok1][ok2][f1][f2] != -1)
            return dp[len][limit1][limit2][ok1][ok2][f1][f2];
        if(len == 0) { 
            return ok1 && ok2 && (f1 == 1 || f2 == 1);
        }  
    
        int up1 = 1, up2 = 1;
        if(limit1) up1 = shuA[len];
        if(limit2) up2 = shuB[len];
        ll res = 0;
        // cout<<len<<" " << up1<<" , " << up2<<endl;
        for(int i=0; i<=up1; i++) {
            for(int j=0; j<=up2; j++) {
                 
                // if(len == 2)cout<<len << " " << i << " , " << j << "  = " << f1 <<" , , " <<f2 << endl;
    
                if(f1 == 1 || f2 == 1) 
                    res += dfs(len-1, limit1 && i == up1, limit2 && j == up2, ok1 || i, ok2 || j, f1, f2);
                else {
                    int F1 = f1, F2 = f2;
                    if((i & j) < shuC[len]) F1 = 2;
                    else if((i & j) > shuC[len]) F1 = max(F1, 1);
    
                    if((i ^ j) > shuC[len]) F2 = 2;
                    else if((i ^ j) < shuC[len]) F2 = max(F2, 1);
                    res += dfs(len-1, limit1 && i == up1, limit2 && j == up2, ok1 || i, ok2 || j, F1, F2);
                }  
            }
    
        }
        dp[len][limit1][limit2][ok1][ok2][f1][f2] = res;
        return res;
    }
     
    int main(){
        int T;  scanf("%d", &T);
        while(T--) {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            memset(dp, -1, sizeof(dp));
            int len = 32;
            for(int i=1; i<=len; i++) shuA[i] = a % 2, a = a >> 1;
             for(int i=1; i<=len; i++) shuB[i] = b % 2, b = b >> 1;
            for(int i=1; i<=len; i++) shuC[i] = c % 2, c = c >> 1;
            printf("%lld
    ", dfs(len, 1, 1, 0, 0, 0, 0));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    python 登录与注册
    python 深浅拷贝
    列表|字典|集合推导式
    正则表达式——笔记
    Python thread
    allure报告自定义logo和名称
    回归测试用例编写思路
    测试用例规范【如何编写测试用例】
    git与pycharm的使用详解(git+gitlab+pycham)
    接口自动化
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/11322959.html
Copyright © 2020-2023  润新知