【题解】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 }

原文地址:https://www.cnblogs.com/gengyf/p/11625480.html

时间: 2024-07-30 07:37:48

【题解】Luogu P3509 [POI 2010] ZAB-Frog 倍增dp的相关文章

题解 luogu P1850 【换教室】

题解 luogu P1850 [换教室] 时间:2019.8.6 一晚上(约 3.5h 写完) 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 \(2n\) 节课程安排在 \(n\) 个时间段上.在第 \(i\)(\(1 \leq i \leq n\))个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 \(c_i\) 上课,而另一节课程在教室 \(d_i\) 进行. 在不提交任何申请的情况下,学生们需要

题解 luogu P5021 【赛道修建】

题解 luogu P5021 [赛道修建] 时间:2019.8.9 20:40 时间:2019.8.12 题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 \(m\) 条赛道. C 城一共有 \(n\) 个路口,这些路口编号为 \(1,2,\dots,n\),有 \(n-1\) 条适合于修建赛道的双向通行的道路,每条道路连接着两个路口.其中,第 \(i\) 条道路连接的两个路口编号为 \(a_i\) 和 \(b_i\),该道路的长度为 \(l_i\).借助这 \(n-1\) 条

题解 HDU 3698 Let the light guide us Dp + 线段树优化

http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 62768/32768 K (Java/Others) Total Submission(s): 759    Accepted Submission(s): 253 Problem Description Plain of despair was

zoj 3649 lca与倍增dp

参考:http://www.xuebuyuan.com/609502.html 先说题意: 给出一幅图,求最大生成树,并在这棵树上进行查询操作:给出两个结点编号x和y,求从x到y的路径上,由每个结点的权值构成的序列中的极差大小——要求,被减数要在减数的后面,即形成序列{a1,a2…aj …ak…an},求ak-aj (k>=j)的最大值. 求路径,显然用到lca. 太孤陋寡闻,才知道原来倍增dp能用来求LCA. 用p[u][i]表示结点u的第1<< i 个祖先结点,则有递推如下: for

Codeforces 1140G Double Tree 倍增 + dp

刚开始, 我以为两个点肯定是通过树上最短路径过去的, 无非是在两棵树之间来回切换, 这个可以用倍增 + dp 去维护它. 但是后来又发现, 它可以不通过树上最短路径过去, 我们考虑这样一种情况, 起点在奇树里面, 终点在偶树里面, 然后这两个点最短路径里面点到对应点的距离都很大, 这种情况下我们就需要从别的地方绕过去, 这样 就不是走树上最短路径了, 但是如果我们将对应点的距离更新成最短距离, 上面这个倍增 + dp的方法就可行了, 所以 我们可以用最短路去更新对应点之间的距离, 将它变成最小值

【题解】POJ2279 Mr.Young′s Picture Permutations dp

[题解]POJ2279 Mr.Young′s Picture Permutations dp 钦定从小往大放,然后直接dp. \(dp(t1,t2,t3,t4,t5)\)代表每一行多少人,判断边界就能dp. 然后你发现\(30^5\)开不下,但是你仔细观察由于它保证\(\sum < 30\)所以你只用开\(30^5 \div 5!\)就好了. 具体为什么我相信你会 //@winlere #include<iostream> #include<cstring> #include

题解 Luogu P2499: [SDOI2012]象棋

关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可以通过改变顺序使这一次移动合法 证明: 考虑到达位置上的那个棋子, 如果它没有到达最终位置, 则我们考虑将该棋子移至下一步, 如果下一步还有没有到达最终位置的棋子, 则也移动它 否则直接调换这两个棋子的移动顺序即可 好的我们去除了题目中的要求: 「移动过程中不能出现多颗棋子同时在某一格的情况」, 接

题解 Luogu P3370

讲讲这题的几种做法: 暴力匹配法 rt,暴力匹配,即把字符串存起来一位一位判相等 时间复杂度$ O(n^2·m) $ 再看看数据范围 $n\le10^5,m\le10^3$ 当场爆炸.当然有暴力分 代码(20pts): #include <bits/stdc++.h> using namespace std; char c[100001][1001]; bool pd(int x, int y) { int l1 = strlen(c[x]), l2 = strlen(c[y]); if(l1

POJ1679 The Unique MST 题解 次小生成树 题解 Kruskal+暴力LCA解法(因为倍增不会写)

题目链接:http://poj.org/problem?id=1679 题目大意: 给你一个简单连通图,判断他的最小生成树是否唯一. 解题思路: 首先(我这里用Kruskal算法)求出它的最小生成树(以下简称MST)以及对应的边,然后构造出这棵MST. 然后我们枚举图上每一条不在此MST上的边,假设这条边的两个端点是 \(u\) 和 \(v\),边权为 \(w\) ,求MST上 \(u\) 到 \(v\) 的树链上的最大边的值是否等于 \(w\),如果等于 \(w\) 就说明 MST 不唯一.