• The Preliminary Contest for ICPC Asia Nanjing 2019


    传送门

    参考资料:

      [1]:官方题解(提取码:w6ny)

    A.The beautiful values of the palace(思维+树状数组+扫描线)

    •题意

      给你一个 $n imes n$ 的矩阵,从右上角开始转圈填充 1~n×n;
      给你 m 个坐标,只有这 m 个坐标对应的位置有权值;
      有 q 次询问,每次询问给出两个点的坐标 $(x_1,y_1),(x_2,y_2)$;
      求由这两个点形成的矩形所包围的区域中,经过处理后的权值加和;
      处理的方法是,将原权值所有数位上的数相加;

    •题解

      对于每次询问,都可以处理成四部分来处理:
        $ans=f(x_2,y_2)-f(x_{1}-1,y_2)-f(x_2,y_{1}-1)+f(x_{1}-1,y_{1}-1)$;
      其中 f(x,y) 指的是由 (1,1)和(x,y) 形成的矩形中的经处理后的权值加和;
      但是由于 n 很大,所以我们不能够通过开数组预处理出所有的前缀和;
      因为没有修改操作,所以我们可以将所有询问离线处理;
      用如下数据结构存储信息:

    1 struct Point
    2 {
    3     int x,y;
    4     int f;
    5     int id;
    6 }p[maxn];

      其中,f 指的是当前区间是加上还是减去,如果需要加上,令 f = 1,反之,令 f = -1;
      id 指的是当前询问的编号;
      定义好数据结构后,对于第 i 次询问,我们需要记录 4 个信息:
        1.$(x=x_2,y=y_2,f=1,id=i)$
        2.$(x=x_{1}-1,y=y_{1}-1,f=1,id=i)$
        3.$(x=x_{1}-1,y=y_2,f=-1,id=i)$
        4.$(x=x_2,y=y_{1}-1,f=-1,id=i)$
      f 取值分别对应上述 f(x,y) 前的符号,如果是加入到 ans 中,f 就取值为 1,反之,取值 -1;
      除了记录询问的信息外,还需要记录 m 个有权值的坐标;
      当然,此处要将这 m 个信息和上述 4*q 个信息区分,区分的方式就是将这 m 个信息的 f 取值为 2;
      将这 q*4+m 个信息记录好后,按照 先x,在y,最后f 的规则排序,就像扫描线求矩形周长并的那道题一样;
      排序策略不对的话直接就导致整个程序 wa;
      排序策略如下:

    1 bool operator < (const Point& obj)const
    2 {
    3     if(x != obj.x)
    4         return x < obj.x;
    5     else if(y != obj.y)
    6         return y < obj.y;
    7     else
    8         return f > obj.f;
    9 }

      离线好这些信息后,还需要一个重要的信息,如何快速求出 m 个有用坐标对应的值;
      你可以参考这篇博客:题解 P2239 【螺旋矩阵】
      根据对称性,很容易求出 (x,y) 所处的圈数 t=min(x,y,n+1-x,n+1-y);
      令 a1=第一圈的维数-1,a2=第二圈的维数-1,...,ai=第i圈的维数-1;
      易得 a1=n-1,a2=n-1-2,.....,ai=n-1-2*(i-1),构成了等差数列;
      令 num1=第一圈右上角的值,num2=第二圈右上角的值,...,numi=第i圈右上角的值;
      易得
        num1=1;
        num2=num1+4*a1;
        num3=num1+4*(a1+a2);
    .    ..........
        numi=num1+4*(a1+a2+...+ai-1);

      因为 a 构成了等差数列,所以 numi=1+4*(a的前i-1项和)
      有了右上角的值,很容易求出当前圈数对应的左下角的值;
        leftDown=numi+2*ai;
      假设 (x,y) 在第 t 圈,其对应的值用 ans 记录;
      根据上述讲解求出 leftDown 后,找到 (x,y)与(t,t) 的曼哈顿距离,记为 cnt;
      那么 ans=leftDown+(x >= y ? -cnt:cnt);
      求出 ans 后,将其各个位的数字加起来就得到了所需的权值;
      然后,从 1 开始枚举 p 中的值,如果当前的 f = 2,那么,就将当前的权值加入到树状数组中;
      反之,更新相应的 ans=f*Sum();
      Sum() 求的是 (1,1)与当前的(x,y) 形成的矩形所包含的权值和;

    •Code

      2019ICPC南京网络赛A.cpp


    B.super_log

    •题意

      $log_{a}^{*} (x)=egin{cases} -1 , if x < 1 \1+log_{a}^{*} (log_{a}x),if x ge 1 end{cases}$

      给出你 a,b,m,让你求解使得 $log_{a}^{*} (x) ge b$ 最小的 x,因为 x 可能很大,所以输出结果对 m 取模;

    •题解

      易得 $log_{a}^{*} (a^a)=2 , log_{a}^{*} (a^{a^a})=3$,那么满足上述条件的最小的 x 为:

        $x=underbrace{a^{a^{a^{cdots}}}}_{b}$;

      那么问题就转化为了求解 $underbrace{a^{a^{a^{cdots}}}}_{b} mod m$ 的值;

      经过这两天的脑补,终于学会了这一类问题的解决方法--欧拉降幂,具体详见我的这篇博客

      因为此题中指数可能小于 $varphi(p)$,所以需要采取实战2的策略,在快速幂中判断 x 与 $varphi(p)$ 的大小关系;

    •Code

      2019ICPC南京网络赛B.cpp


     F.Greedy Sequence(set+upper_bound()+思维)

    •题意

      给你一个包含 n 个数的序列 a,其中 a 中存的数为 1~n 的排列;

      定义一个二维数组 s;

      s 中一共有 n 行,每行有 n 个数;

      定义 s 数组:

        ① $s_{i}[1]=i$

        ②$forall  i in[1,n],j in [2,n],s_{i,j} le s_{i,j-1}$,即 $s_i$是个非增序列;

        ③对于 $s_i$ 中的第 j( j > 1 ) 个数,$s_{i,j}$ 在 a 中的位置与 $s_{i,j-1}$ 在 a 中的位置之差的绝对值不能超过 k;

        ④ $s_i$ 中的第 j( j > 1) 个数,要尽可能的大;

        ⑤如果 $s_{i,j}$ 后,在 a 中找不到满足条件 ②③ 的数,并且 $s_i$ 不足 n 个数,用 0 填充剩余的数;

      输出 |s1|,|s2|,...,|sn|,|si|表示 s 中第 i 行包含的数的个数;

    •题解(by官方)

      

    •Code

      2019ICPC南京网络赛F.cpp

  • 相关阅读:
    DHCP服务器搭建
    linux文件通配符
    NTP服务器搭建
    .Net下MoongoDB的简单调用
    Mac 下安装配置MongoDB讲解
    Redis 介绍学习
    PostgreSQL学习之路一 安装
    CentOS安装PostgreSQL
    离线安装PostgreSQL11.6
    PostgreSQL 安装扩展插件plpython3u执行python,访问页面或者第三方程序
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/11443355.html
Copyright © 2020-2023  润新知