沪粤联赛 2024.2

A

用快速幂。

pair<ldb, ll> fpow(ldb a, int k) {
  ll A = 0, R = 0;
  while (a >= 10) {
    a /= 10;
    A++;
  }
  ldb r = 1.0;
  while (k) {
    if (k&1) {
      r = r * a;
      R += A;
      while (r >= 10) {
        r /= 10;
        R++;
      }
    }
    k >>= 1;
    a = a * a;
    A *= 2;
    while (a >= 10) {
      a /= 10;
      A++;
    }
  }
  return {r, R};
}

注意这里一定要用 long double a,不要偷懒用两个变量只记录整数和小数后一位。

B

总有一个最优解,直线经过至少两条线段的端点。

于是枚举是哪两条线段的端点,然后枚举所有线段,判断直线是否经过。

如何判断一条直线是否经过一条线段?当然可以直接解析式求交点是否在范围内,但这里有一种不用推式子、精度损失,用到向量的方法。

首先判断是否有端点在直线上。

如若没有,就要判断端点是否在直线两侧。设端点为 \(l,r\),在直线上取两个点 \(p_1,p_2\)。记 \(p_1(x_1,y_1),p_2(x_2,y_2),l(x_l,y_l),r(x_r,y_r)\)。只需要判断 \((p_1,p_2,l),(p_1,p_2,r)\) 这两个三角形的有向面积是否一正一负。若是,则表示端点在直线两侧;否则在同侧。

为什么?因为如果在直线两侧,这两个三角形的方向,也就是相对于直线的顺/逆时针方向是不同的,那顺时针的有向面积应该是负数,逆时针的应该是正数。

怎么求三角形的有向面积?若以 \(p_1\) 为原点,则 \(p_2,p_{l/r}\) 相对于 \(p_1\) 都有各自的向量:\((x_2-x_1,y_2-y_1),(x_l-x_1,y_l-y_1),(x_r-x_1,y_r-y_1)\)

\(p_1\rightarrow p_2\rightarrow p_l\) 的有向面积,可以用 \(p_2,p_l\) 的向量叉积求出:\((x_2-x_1)(y_l-y_1)-(x_l-x_1)(y_2-y_1)\)。另一个三角形也是如此。判断这两个值是否一正一负即可。

C

容斥原理套 DP。

D

Nim 游戏:若每一堆石子数量的异或非 \(0\),则先手必胜。

如果只有操作 \(3\)\(w_x=w_x\bigoplus a_x\bigoplus (a_x+k)\)。简单。

加上操作 \(1\),可以用启发式合并,显然兼容操作 \(3\)

操作 \(2\)可以用 01Trie 维护区间 \(+1\)

从低到高插入数,建立 01Trie。一次全局 \(+1\),等价于交换 \(0,1\) 子树,然后沿着此时的 \(0\) 边继续递归交换左右儿子。

显然 01Trie 也能删除、插入和启发式合并。

对于

posted @ 2024-03-04 18:50  FLY_lai  阅读(9)  评论(0编辑  收藏  举报