zoukankan      html  css  js  c++  java
  • Technocup 2019

    http://codeforces.com/contest/1030

    B. Vasya and Cornfield

    判断点是否在矩形内(包括边界)

    把每条边转化为一个不等式

     1  public static void main(String[] args) {
     2         IO io = new IO();
     3         int n = io.nextInt(), d = io.nextInt();
     4         int t = io.nextInt();
     5         while (t-- > 0) {
     6             int x = io.nextInt(), y = io.nextInt();
     7             io.println(d <= x + y && x + y <= 2 * n - d &&
     8                     -d <= y - x && y - x <= d ? "YES" : "NO");
     9         }
    10     }

    C. Vasya and Golden Ticket

    给你一串数列,问该数列是否可以分为若干相邻且不相交的区间,每个区间和相等

    枚举第一个区间的所有情况

     1     public static void main(String[] args) {
     2         IO io = new IO();
     3         int n = io.nextInt();
     4         int[] sum = new int[n + 1];
     5         int s = 0, k = 0, j;
     6         for (int i = 1; i <= n; i++) sum[i] = io.nextChar() - '0' + sum[i - 1];
     7         for (int i = 1; i < n; i++)
     8             for (k = i, j = i + 1; j <= n; j++)
     9                 if (sum[j] - sum[k] == sum[i]) {
    10                     k = j;
    11                     if (sum[k] == sum[n]) {
    12                         io.println("YES");
    13                         return;
    14                     }
    15                 }
    16         io.println("NO");
    17     }

    D. Vasya and Triangle

    问是否存在三个点,每个点的横纵坐标范围是[0,n]、[0,m],且三个点围成的三角形面积为n*m/k

    我们选择坐标轴上的点(0,0)、(x,0)、(0,y),得到x*y=2*m*n/k,关键是k的消去可能是2、n、m都贡献了因子,所以才要求最大公约数保证整除,2m算一个数还是2n算一个数要分情况讨论,不然乘以2了还只除以gcd=1会超过范围

     1     public static void main(String[] args) {
     2         IO io = new IO();
     3         long n = io.nextInt(), m = io.nextInt(), k = io.nextInt();
     4         if (n * m * 2 % k != 0) io.println("NO");
     5         else {
     6             long g = gcd(2 * n, k);
     7             if (g == 1) m = 2 * m / k;
     8             else {
     9                 n = 2 * n / g;
    10                 m = m * g / k;
    11             }
    12             io.println("YES");
    13             io.println("0 0");
    14             io.println(n + " 0");
    15             io.println("0 " + m);
    16         }
    17     }

    E. Vasya and Good Sequences

    给你一个数列,对于每个数,你可以任意交换它的二进制表示里的任意一对01,问这个数列最多有几个连续的区间,使其操作后的数字异或和为0

    当区间内所有数的1的总和为偶数且不会出现一半以上的1都在1个数里时,该区间合法 。具体做法:求出所有可能,然后减去区间1的总和为偶数且一半以上的1都在1个数里的情况;

    a[i]:将每个数替换为其二进制表示中1的个数

    s[i]:a[i]前缀和,此时每个区间都可表示为si-sj的形式。当si为奇数时sj必须存在且也为奇数,这样组成的区间[j,i]里1的个数和才为偶数,此时si的贡献为[1,i)里奇数项的个数;当s[i]为偶数时,其贡献为[1,i]里偶数项的个数,多出来的情况是sj不存在的[1,i]。

    (该题有个小却一缺即超的优化,已在代码里标出)

     1     public static void main(String[] args) {
     2         IO io = new IO();
     3         int n = io.nextInt();
     4         int[] a = new int[n + 1];
     5         int[] s = new int[n + 1];
     6         int[] s1 = new int[n + 1];
     7         int[] s0 = new int[n + 1];
     8         long ans = 0, t, max;
     9         for (int i = 1; i <= n; i++)
    10             for (t = io.nextLong(); t != 0; t >>= 1)
    11                 a[i] += (t & 1);
    12         for (int i = 1; i <= n; i++) {
    13             s[i] = s[i - 1] + a[i];
    14             s1[i] = s1[i - 1];
    15             s0[i] = s0[i - 1];
    16             if (s[i] % 2 == 1) ans += s1[i]++;
    17             else ans += ++s0[i];
    18         }
    19         for (int i = 1; i <= n; i++) {
    20             max = 0;
    21             //j - i + 1 < 65
    22             for (int j = i; j <= n && j - i + 1 < 65; j++) {
    23                 max = Math.max(max, a[j]);
    24                 if ((s[j] - s[i - 1]) % 2 == 0 && s[j] - s[i - 1] < max * 2) ans--;
    25             }
    26         }
    27         io.println(ans);
    28     }

    F. Putting Boxes Together

    一列上有n个盒子,每个盒子有自己的重量,移动一个重量为wi的盒子一个单位花费能量wi,现在有两种操作:1、改变某个盒子的重量,2、输出把第[l,r]的盒子放在一起(起点任意,只要每个都挨在一起)所需的最小能量

    (树状数组:https://www.cnblogs.com/towerbird/p/9941030.html

    不妨首先把盒子都移到[1,n],我们贪心地认为能量最少的方案应该是[l,r]里wi正好把总w分成最均等的两部分的盒子mid不移动,则答案是把所有盒子移动到[1,n]的能量减去右移a[mid]-mid的能量,注意mid左边的盒子贡献要取负数,右边的取正数。用二分查找找出mid。

    (a、w下标以0开始怎么都错……为什么啊)

     1     private static final int c = (int) (2e5 + 10), mod = (int) (1e9 + 7);
     2     static int n, q;
     3     static long[] a = new long[c];
     4     static long[] w = new long[c];
     5     static long[][] tre = new long[c][2];
     6 
     7     static void update(int i, long x, int j) {
     8         while (i <= n) {
     9             tre[i][j] += x;
    10             if (j == 1) tre[i][j] %= mod;
    11             i += i & -i;
    12         }
    13     }
    14 
    15     static long query(int i, int j) {
    16         long s = 0;
    17         while (i > 0) {
    18             s += tre[i][j];
    19             if (j == 1) s %= mod;
    20             i -= i & -i;
    21         }
    22         return s;
    23     }
    24 
    25     public static void main(String[] args) {
    26         IO io = new IO();
    27         n = io.nextInt();
    28         q = io.nextInt();
    29         for (int i = 0; i < n; i++) a[i] = io.nextLong();
    30         for (int i = 0; i < n; i++) {
    31             update(i + 1, w[i] = io.nextLong(), 0);
    32             update(i + 1, w[i] * (a[i] - i), 1);
    33         }
    34         while (q-- > 0) {
    35             int x = io.nextInt(), y = io.nextInt();
    36             if (x < 0) {
    37                 x = -x - 1;
    38                 update(x + 1, y - w[x], 0);
    39                 update(x + 1, (y - w[x]) * (a[x] - x), 1);
    40                 w[x] = y;
    41             } else {
    42                 long s = query(y, 0) + query(x - 1, 0), c = 0;
    43                 int mid = 0;
    44                 for (int i = 17; i >= 0; i--)
    45                     if (mid + (1 << i) < n && (c + tre[mid + (1 << i)][0]) * 2 < s) {
    46                         mid += 1 << i;
    47                         c += tre[mid][0];
    48                     }
    49                 long a1 = query(y, 1) - 2 * query(mid, 1) + query(x-1, 1);
    50                 long a2 = query(y, 0) - 2 * query(mid, 0) + query(x-1, 0);
    51                 //+ 2 * mod是出现了负无穷大的情况
    52                 long ans = a1 % mod - a2 % mod * (a[mid] - mid) % mod + 2 * mod;
    53                 io.println(ans % mod );
    54 
    55             }
    56         }
    57     }

    G. Linear Congruential Generator——我选择狗带o( ̄┰ ̄*)ゞ

  • 相关阅读:
    WebSocket资料
    HTML5新增特性
    CSS3新增选择器
    HTM5基本语法
    HTML语义化
    浏览器内核分类
    Layui表格的单双击处理
    c++ cin读取多行数字
    计算机视觉中关于人脸的一些任务
    python实现NMS和softNMS代码
  • 原文地址:https://www.cnblogs.com/towerbird/p/9939435.html
Copyright © 2011-2022 走看看