• 8.2集训


    上午

    考试

    下午

    第一题

    一句话题意:给出两个(1) (to) (n)的序列,定义(T(a,b))(a)(b)在序列中的距离

    其计算公式为:(下标_{b所在的位置} - 下标_{a所在的位置})

    找出两个序列中,(max({T_1(a,b),+T_2(a,b))})

    看一组例子:

    A:3 2 1 4 5
    B:2 5 1 3 4
    

    考虑(2)(4)这两个数字对答案的贡献,

    显然:(ans_{当前} = (下标_{4所在的A系列位置}-下标_{2所在的A序列位置}) +(下标_{4所在的B系列位置}-下标_{2所在的B序列位置}))

    合并之后得到:(ans_{当前} = (下标_{4所在的A系列位置} + 下标_{4所在的B系列位置})-(下标_{2所在的A序列位置} + 下标_{2所在的B序列位置}))

    A序列中的(2)(4)是递增分布的,考虑,如果B序列中出现(4.......2)的情况怎么办?

    或者A序列中(4.......2),而B序列中(2......4)怎么办?

    也就是说B序列与A序列的“顺序不同”(需要感性理解)

    这时候我们考虑把下标从右往左标上一圈,原来不是从左往右吗?现在所谓的“逆序”,我们从右往左,实现也很简单,(n-下标_{当前}+1)就是你逆序之后的下标

    给出自己的代码(借鉴了Tethysdalao的代码)

    #include <bits/stdc++.h>
    #define LL long long
    #define debug
    using namespace std;
    
    inline long long read() {
       long long s = 0, f = 1; char ch;
       while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
       for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
       return s * f;
    }
    
    const int N = 1e6+66;
    
    int n, res, ans_s_max, ans_s_min = N<<1, ans_n_max, ans_n_min = N<<1;
    int a[N], b[N], f[N];
    
    inline void shuruyijijiejueheshuchu() {
       n = read();
       for (int i = 1; i <= n; ++ i) a[i] = read();
       for (int i = 1; i <= n; ++ i) {
          b[i] = read();
          f[b[i]] = i;
       }
       for (int i = 1; i <= n; ++ i) {
          ans_s_max = max(ans_s_max, i + f[a[i]]);
          ans_s_min = min(ans_s_min, i + f[a[i]]);
          ans_n_max = max(ans_n_max, i + n-f[a[i]]+1);
          ans_n_min = min(ans_n_min, i + n-f[a[i]]+1);
          res = max(res, ans_s_max - ans_s_min);
          res = max(res, ans_n_max - ans_n_min);
       }
       cout << res;
    }
    
    inline int thestars() {
       shuruyijijiejueheshuchu();
       fclose (stdin), fclose (stdout);
       return 0;
    }
    
    int youngore = thestars();
    
    signed main() {;}
    /*
    5
    2 1 5 3 4
    4 2 5 1 3
    */
    

    我懒得去写具体的代码分析了,日后补吧

    第二题

    一句话题意:求(egin{aligned}sum_{i=0}^xC_{x}^i*C_{y}^{z+i}\%998244353end{aligned})

    其中数据:(T<=10000,0<=x,y,z<=1000000)

    可曾听闻范德蒙德卷积?

    然后就没了

    (egin{aligned}sum_{i=0}^k{C_n^iC_{m}^{k-i}}=C_{n+m}^{k}end{aligned})

    具体详见Ame__

    给出代码:

    #include <bits/stdc++.h>
    #define int long long
    #define debug
    using namespace std;
    
    const int N = 1e7+66, mod = 998244353;
    
    inline int read() {
       int s = 0, f = 1; char ch;
       while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
       for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
       return s * f;
    }
    
    int x, y, z, t;
    int js[N];
    
    inline int ksm(int a, int b) {
       if (!b) return 1;
       if (b&1) return a*ksm(a,b-1);
       int tmp = ksm(a, b/2)%mod;
       return tmp*tmp%mod;
    }
    //这个快速幂我没有测
    inline int C(int n, int m) {
       if (n < m) return 0;
       return js[n]*ksm(js[m]*js[n-m]%mod, mod-2)%mod;
    }
    
    inline int Lucas(int n, int m) {
       if (!m) return 1;
       return C(n%mod, m%mod)*Lucas(n/mod, m/mod)%mod;
    }
    
    inline void shuruhejiejueheshuchu() {
       t = read();
       js[0] = 1, js[1] = 1;
       for (int i = 2; i <= N; ++ i) js[i] = js[i - 1]*i%mod;
       while (t -- > 0) {
          // cin >> x >> y >> z;
          x = read(), y = read(), z = read();
          int sum =  Lucas(x+y, x+z)%mod;
          cout << sum << '
    ';
       }
    }
    
    inline int thestars() {
       shuruhejiejueheshuchu();
       return 0;
    }
    
    int youngore = thestars();
    
    signed main() {;}
    

    这题tmd卡快读,艹,我用(cin)全T飞了

    第三题

    一句话题意:给你个序列,每次要异或一个数,还要查询一个判定器,其中(n leq 1e6)

    显然暴力(n^2),正解是:(01Tire),艹,我就是tm讲的Trie树,我自己没看出来,老往主席树什么玩意的想去了

    关键是前几天学长好几道异或的题,都跟01Trie树没关系啊,我知道是01Trie树之后,当场mmp

    后来gzh奆佬直言:学过01Trie树的一眼就能看出来(于是口吐不清的开始了他迷迷糊糊的讲解)

    具体思路:在01Trie树上搞一搞就可以了

    给出代码:

    #include <bits/stdc++.h>
    #define LL long long
    #define debug
    using namespace std;
    
    const int N = 6e6+66;
    
    int n, t, x, y, cnt;
    int ch[N][6], tag[N];
    
    inline void shuruyijijiejueheshuchu() {
       cin >> n >> t;
       for (int i = 1; i <= n; ++ i) {
          int now = 0;
          cin >> x;
          for (int j = 16; j >= 0; -- j) {
             if (!ch[now][x>>j&1]) ch[now][x>>j&1] = ++ cnt;
             now = ch[now][x>>j&1];
             ++ tag[now];
          }
       }
       while (t --> 0) {
          int res = 0, now = 0;
          cin >> x >> y;
          for (int j = 16; j >= 0; -- j) {
             if (y>>j&1) res += tag[ch[now][x>>j&1]];
             now = ch[now][(y>>j&1)^(x>>j&1)];
             if (!now) break;
          }
          if (now) res += tag[now];
          cout << res << '
    ';
       }
    }
    
    inline int thestars() {
       shuruyijijiejueheshuchu();
       return 0;
    }
    
    int youngore = thestars();
    
    signed main() {;}
    /*
    5 5
    7 6 7 3 4
    2 6
    1 8
    8 7
    3 2
    6 2
    */
    
    
  • 相关阅读:
    Java NIO系列教程(十二) Java NIO与IO
    Java NIO系列教程(十一) Pipe
    Java NIO系列教程(十) Java NIO DatagramChannel
    Java NIO系列教程(九) ServerSocketChannel
    C#使用cmd运行命令并返回控制台输出信息
    分割nginx日志
    redis启动警告解决
    git worktree 目录修复
    git worktree 稀疏检出(sparseCheckout)
    python json dumps datetime类型报错
  • 原文地址:https://www.cnblogs.com/yszhyhm/p/13419781.html
Copyright © 2020-2023  润新知