• AGC018E Sightseeing Plan


    题目链接 参考博客

    从左下矩形出发经过中间矩形的一个点 (p) 再到右上矩形的方案数。值域 (le 10^6),方案不同的意思是 (p) 或 路径上的点集不同。


    (默认向上为 (x) 轴正方向,向右为 (y) 轴正方向)

    这题好不可做啊,简化一下试试?

    点到点

    [(x,y) o (x',y') = G((x,y),(x',y')) = {x'-x+y'-y choose x'-x} ]

    点到矩形

    [egin{aligned} &G((0,0), (x,y))\ &= F(x,y)\ &= sum_{i=0}^xF(i,y-1)\ &= sum_{i=0}^xF(i,y-2) + sum_{i=0}^{x-1}F(i,y-1)\ &= ...\ &= sum_{i=0}^{x-1}sum_{j=0}^{y-1}F(i,j) + F(0,y)\ &= sum_{i=0}^{x-1}sum_{j=0}^{y-1}F(i,j) + 1 end{aligned}]

    差分即可。

    [F(x' + 1, y' + 1) - F(x, y' + 1) - F(x' + 1, y') + F(x, y) ]

    矩形到矩形

    [egin{aligned} &sum_{i=0}^{fx}sum_{j=0}^{fy}sum_{(k,l)in Mat_2} G((i,j),(k,l))\ &= sum_{(i,j) in Mat_1}G((i,j),(x_0,y_0) + ... + G((i,j),(x_3,y_3))\ &= G((x_0',y_0'),(x_0,y_0)) + ... + G((x_3',y_3'),(x_3,y_3)) end{aligned}]

    差分再差分,(4 imes 4) 次计算。

    矩形经过矩形到矩形

    枚举中间矩形的“进入”操作,只要有“进入”操作,就算合法。(“进入”操作有点插头的感觉)

    但是一段路径在中间矩形的长度为 (len),那么将贡献 (len) 次。

    记路径在中间矩形的部分的起点为 ((x,y)),出点为 ((x',y')),那么

    [egin{aligned} len &= y'-y + x'-x + 1\ &= -(x+y) + (x' + y' + 1) end{aligned}]

    于是可以拆贡献为起点的贡献和终点的贡献。主要还是根据“只要有进入操作,就算合法”以及“只要有退出操作,就算合法”。

    复杂度:(O(n))

    关键代码:

    inline ll G(int sx, int sy, int fx, int fy) {
      int x = fx - sx, y = fy - sy;
      return get_c(x + y, x);
    }
    
    inline void work() {
      int dx[8] = {X1 - 1, X1 - 1, X2, X2, X5, X5, X6 + 1, X6 + 1};
      int dy[8] = {Y1 - 1, Y2, Y1 - 1, Y2, Y5, Y6 + 1, Y5, Y6 + 1};
      int tp[8] = {1, -1, -1, 1, 1, -1, -1, 1};
      ll ans = 0;
      for (int jzp = 0; jzp < 4; ++jzp) {
        int sx = dx[jzp], sy = dy[jzp];
        for (int zzz = 4; zzz < 8; ++zzz) {
          int fx = dx[zzz], fy = dy[zzz];
          ll res = 0;
          int ntp = tp[jzp] * tp[zzz];
          int x, y;
          for (x = X3, y = Y3; x <= X4; ++x) {
            res = (res - G(sx, sy, x, y - 1) * G(x, y, fx, fy) % P * (x + y)) % P;
          }
          for (x = X3, y = Y3; y <= Y4; ++y) {
            res = (res - G(sx, sy, x - 1, y) * G(x, y, fx, fy) % P * (x + y)) % P;
          }
          for (x = X3, y = Y4; x <= X4; ++x) {
            res = (res + G(sx, sy, x, y) * G(x, y + 1, fx, fy) % P * (x + y + 1)) % P;
          }
          for (x = X4, y = Y3; y <= Y4; ++y) {
            res = (res + G(sx, sy, x, y) * G(x + 1, y, fx, fy) % P * (x + y + 1)) % P;
          }
          ans = (ans + ntp * res) % P;
        }
      }
      printf("%lld
    ", (ans % P + P) % P);
    }
    
  • 相关阅读:
    抽象类和接口
    回调函数
    Spring Aop、拦截器、过滤器的区别
    事务
    SQL 模糊查询条件的四种匹配模式
    shell编程(二)
    shell编程(一)
    shell介绍
    字符验证码
    selenium
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13623906.html
Copyright © 2020-2023  润新知