题解Luogu P3509 [POI 2010] ZAB-Frog 倍增dp

Posted gengyf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解Luogu P3509 [POI 2010] ZAB-Frog 倍增dp相关的知识,希望对你有一定的参考价值。

单调队列处理第k远的点

倍增跳点

滚(动数组)一维空间就能开下了

注意$m≤10^{18}$的读入

code

技术图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 namespace gengyf{
 4 #define ll long long
 5 const int maxn=1e6+10;
 6 inline ll read(){
 7     ll x=0,f=1;
 8     char c=getchar();
 9     while(c<0||c>9){if(c==-)f=-1;c=getchar();}
10     while(c>=0&&c<=9){x=(x*10)+c-0;c=getchar();}
11     return x*f;
12 }
13 ll n,k,m,a[maxn],p[maxn];
14 int f[maxn][2],g[maxn];
15 int main(){
16     n=read();k=read();m=read();
17     for(int i=1;i<=n;i++){
18         a[i]=read();
19     }
20     ll l=1,r=k+1,lim=log2(m)+1;
21     for(int i=1;i<=n;i++){
22         while(r<n && a[r+1]-a[i]<a[i]-a[l]){
23             l++,r++;
24         }
25         f[i][0]=(a[r]-a[i]>a[i]-a[l]?r:l);
26     }
27     if(m&1){
28         for(int i=1;i<=n;i++){
29             g[i]=f[i][0];
30         }
31     }
32     else {
33         for(int i=1;i<=n;i++){
34             g[i]=i;
35         }
36     }
37     r=1;p[0]=1;
38     for(int i=1;i<=lim;i++) p[i]=p[i-1]<<1;
39     for(int j=1;j<=lim;j++){
40         for(int i=1;i<=n;i++){
41             f[i][r]=f[f[i][r^1]][r^1];
42         }
43         if(m&p[j]){
44             for(int i=1;i<=n;i++){
45                 g[i]=f[g[i]][r];
46             }
47         }
48         r^=1;
49     }
50     for(int i=1;i<=n;i++){
51         printf("%d ",g[i]);
52     }
53     return 0;
54 }
55 }
56 signed main(){
57   gengyf::main();
58   return 0;
59 }
View Code

 

以上是关于题解Luogu P3509 [POI 2010] ZAB-Frog 倍增dp的主要内容,如果未能解决你的问题,请参考以下文章

POI2010ANT-Antisymmetry

Luogu3540 [POI2012]SQU-Squarks 题解

luogu P3512 [POI2010]PIL-Pilots

题解Luogu P3488 [POI2009]LYZ-Ice Skates

[luogu3505][bzoj2088][POI2010]TEL-Teleportation

luogu P3592 [POI2015]MYJ