Luogu P1725 琪露诺

本文介绍了解决LuoguP1725琪露诺问题的方法,通过DP算法和单调队列进行状态转移优化,将时间复杂度从O(N^2)降低至O(N)。

题目

Luogu P1725 琪露诺

分析

看上去像一道DP题。用dp[i]表示到达坐标i时的最大冰冻指数,可以得到转移方程:

dp[i]=max{dp[k]}+a[i],k∈[i-l,i-r]

题目中提到,只要她下一步的位置编号大于N就算到达对岸,因此枚举i时要[l,n+r),因为[0,l]的部分她不可能到达,但[n,n+r)的部分都有可能是到对岸之前的那一步,走到对岸时到达的坐标。能够转移到当前坐标i的范围是[i-l,i-r](可以反推帮助理解),所以k∈[i-l,i-r]。总复杂度O(N^2),显然爆炸。
于是考虑优化,静心观察可以发现,[i-l,i-r]中只有最大的a[k]才会作为转移向下一步的状态,因为各个子区间是以一个单位坐标向对岸移动的,所以在每一个子区间中取较小的a[k]向之后的坐标转移不如选择最大的a[k]要优。换言之,这种贪心是正确的,因为一个坐标会被多个区间覆盖,所以不许考虑通常题目中舍弃当前最有以求得下一步更优,来达到全局最优的目的。
那么这显然具有单调性!维护一个单调递增的队列,存放每一个[i-l,i-r]中最优的a[k]的坐标。由于每个坐标或进队或出队,因此相当于进行了O(N)的访问,总复杂度即为O(N)。

代码

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=200002;
int a[maxn*2],dp[maxn*2],q[maxn*10];
int main()
{
    int n,l,r;
    scanf("%d%d%d",&n,&l,&r);
    for(int i=0;i<=n;i++)
        scanf("%d",&a[i]);
    int head=1,tail=1;
    for(int i=l;i<n+r;i++)
    {
        while(head<=tail&&dp[i-l]>=dp[q[tail]]) 
            tail--;
        q[++tail]=i-l;
        while(head<=tail&&q[head]<i-r)
            head++;
        dp[i]=dp[q[head]]+a[i];
    }
    int ans=-2147483647;
    for(int i=n+1;i<=n+r;i++)   
        ans=max(ans,dp[i]);
    printf("%d",ans);
    return 0; 
}
请修改一下题面,题意不要发生改变,公式不要发生改变,将主人公换成中雅的数学老师胡特,多写一点,题目自拟 题面: ## 题目背景 上白泽慧音在给雾之湖的妖精们讲课。 某天,慧音在上数学课时,提到了一种非常有趣的记号:**高德纳箭号表示法**。它可以用来描述非常巨大的数字。~~比如紫的年龄。~~ 对于非负整数 $a, b$ 和正整数 $n$,高德纳箭号表示法的定义为: $$a \uparrow^n b = \begin{cases} 1\ (b = 0) \\ a^b\ (n = 1\ \operatorname{and}\ b > 0) \\ a \uparrow^{n - 1} (a \uparrow^n (b - 1))\ (n > 1\ \operatorname{and}\ b > 0) \end{cases}$$ 一些简单的例子: - $2 \uparrow 31 = 2^{31} = 2147483648$ - $2 \uparrow \uparrow 4 = 2^{2^{2^2}} = 2^{2^4} = 2^{16} = 65536$ 注: 1. $a \uparrow b$ 与 $a \uparrow^1 b$ 相同; 2. $a \uparrow \uparrow b$ 与 $a \uparrow^2 b$ 相同; 3. 请注意幂运算的顺序。 ## 题目描述 慧音希望解决以下关于 $x$ 的方程: $$a \uparrow^n x \equiv b \pmod p$$ 其中,$a, n, b, p$ 为已知的常数,$x$ 为未知数。 被高德纳箭号表示法搞得云里雾里的,但是她不想被头槌。你能帮帮她吗? ## 输入格式 **本题有多组测试数据。** 第一行,一个整数 $T$,表示数据组数。 对于每组数据: 一行,四个整数 $a, n, b, p$。 ## 输出格式 对于每组数据,输出一行,一个整数,如果原方程有解,输出该方程的最小非负整数解;否则,输出 $-1$。 ## 输入输出样例 #1 ### 输入 #1 ``` 3 2 1 1 3 3 1 2 7 7 1 2 4 ``` ### 输出 #1 ``` 0 2 -1 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 3 2 2 4 7 3 2 4 6 5 2 1 3 ``` ### 输出 #2 ``` 2 -1 0 ``` ## 输入输出样例 #3 ### 输入 #3 ``` 3 4 3 5 8 2 3 9 11 6 3 1 5 ``` ### 输出 #3 ``` -1 3 0 ``` ## 说明/提示 **本题开启捆绑测试。** | Subtask | $n$ | $p$ | $T$ | 分值 | 时限 | | :------: | :------: | :------: | :------: | :------: | :------: | | $1$ | $n = 1$ | $2 \leq p \leq 10^9$ 且 $p$ 为质数 | $1 \leq T \leq 100$ | $15 \operatorname{pts}$ | $2.00 \operatorname{s}$ | | $2$ | $n = 2$ | 无特殊限制 | $1 \leq T \leq 5 \times 10^3$ | $25 \operatorname{pts}$ | $1.00 \operatorname{s}$ | | $3$ | $n = 3$ | 无特殊限制 | 无特殊限制 | $60 \operatorname{pts}$ | $2.00 \operatorname{s}$ | 对于 $100\%$ 的数据,$1 \leq a \leq 10^9$,$1 \leq n \leq 3$,$0 \leq b < p \leq 10^9$,$1 \leq T \leq 2 \times 10^4$。
最新发布
09-06
## 题目背景 中雅的数学老师胡特正在给同学们讲解一种非常有趣的数学记号。 这天,在讲解关于超大数的表示方法时,胡特提到了一个名叫**高德纳箭号表示法**的概念。它可以用来表示那些大得难以想象的数字,比如描述宇宙中所有粒子的总数都显得微不足道的那种。~~当然,这还不包括紫的年龄。~~ 对于非负整数 $a, b$ 和正整数 $n$,高德纳箭号表示法的定义如下: $$a \uparrow^n b = \begin{cases} 1\ (b = 0) \\ a^b\ (n = 1\ \operatorname{and}\ b > 0) \\ a \uparrow^{n - 1} (a \uparrow^n (b - 1))\ (n > 1\ \operatorname{and}\ b > 0) \end{cases}$$ 胡特老师还举了一些简单的例子,帮助同学们理解箭号的威力: - $2 \uparrow 31 = 2^{31} = 2147483648$ - $2 \uparrow \uparrow 4 = 2^{2^{2^2}} = 2^{2^4} = 2^{16} = 65536$ 在讲解过程中,胡特特别提醒同学们注意幂运算的顺序问题,这会直接影响到最终结果。 ## 题目描述 为了加深同学们的理解,胡特布置了一道挑战性题目: 给定整数 $a, n, b, p$,求满足以下方程的最小非负整数解 $x$: $$a \uparrow^n x \equiv b \pmod p$$ 其中,$a, n, b, p$ 为已知的常数,$x$ 是未知数。 胡特说:“这道题可不简单,但只要你们掌握了箭号表示法的递归本质,就一定能解出来!”同学们纷纷点头,但心里却有些打鼓。 你能帮他们解决这个问题吗? ## 输入格式 **本题有多组测试数据。** 第一行,输入一个整数 $T$,表示测试数据的组数。 接下来每组数据占一行,包含四个整数 $a, n, b, p$。 ## 输出格式 对于每组数据,输出一行,一个整数: - 如果方程有解,输出最小的非负整数解 $x$; - 否则,输出 $-1$。 ## 输入输出样例 #1 ### 输入 #1 ``` 3 2 1 1 3 3 1 2 7 7 1 2 4 ``` ### 输出 #1 ``` 0 2 -1 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 3 2 2 4 7 3 2 4 6 5 2 1 3 ``` ### 输出 #2 ``` 2 -1 0 ``` ## 输入输出样例 #3 ### 输入 #3 ``` 3 4 3 5 8 2 3 9 11 6 3 1 5 ``` ### 输出 #3 ``` -1 3 0 ``` ## 说明/提示 **本题开启多组数据捆绑测试。** | Subtask | $n$ | $p$ | $T$ | 分值 | 时限 | | :------: | :------: | :------: | :------: | :------: | :------: | | $1$ | $n = 1$ | $2 \leq p \leq 10^9$ 且 $p$ 为质数 | $1 \leq T \leq 100$ | $15 \operatorname{pts}$ | $2.00 \operatorname{s}$ | | $2$ | $n = 2$ | 无特殊限制 | $1 \leq T \leq 5 \times 10^3$ | $25 \operatorname{pts}$ | $1.00 \operatorname{s}$ | | $3$ | $n = 3$ | 无特殊限制 | 无特殊限制 | $60 \operatorname{pts}$ | $2.00 \operatorname{s}$ | 对于 $100\%$ 的数据,满足以下条件: - $1 \leq a \leq 10^9$ - $1 \leq n \leq 3$ - $0 \leq b < p \leq 10^9$ - $1 \leq T \leq 2 \times 10^4$ ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值