The Preliminary Contest for ICPC Asia Nanjing 2019


 

 

傳送門

 

參考資料:

  [1]:官方題解(提取碼:w6ny)

 

A.The beautiful values of the palace(思維+樹狀數組+掃描線)

•題意

  給你一個 $n\times 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)=\begin{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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM