ToB企服应用市场:ToB评测及商务社交产业平台
标题:
P1081 [NOIP2012 进步组] 开车观光
[打印本页]
作者:
一给
时间:
2024-7-30 08:13
标题:
P1081 [NOIP2012 进步组] 开车观光
思绪:
首先令 \(nxt1_i\) 表示右侧最近的城市间隔(\(id1_i\) 为编号),令 \(nxt2_i\) 表示右侧第二近的城市编号(\(id2_i\) 为编号);可以利用 set 找出离这个城市最近的 \(4\) 个城市(前面两个,后面两个)。
定义:
\(f_{i,j}\) 表示从 \(i\) 点出发走 \(2^j\) 轮末了到达的位置。
\(dp1_{i,j}\) 表示从 \(i\) 点出发走 \(2^j\) 轮末了 A 走过的间隔。
\(dp2_{i,j}\) 表示从 \(i\) 点出发走 \(2^j\) 轮末了 B 走过的间隔。
初始化:
\[f_{i,0} = id1_{id2_i}\]
\[dp1_{i,0} = nxt2_{i}\]
\[dp2_{i,0} = nxt1_{id2_i}\]
状态转移方程为:
\[f_{i,j} = f_{f_{i,j-1},j-1}\]
\[dp1_{i,j} = dp1_{i,j-1} + dp1_{f_{i,j-1},j-1}\]
\[dp2_{i,j} = dp2_{i,j-1} + dp2_{f_{i,j-1},j-1}\]
此时对于询问 \(1\) 和询问 \(2\):
本质上是求出从每个城市出发后 \(A\) 走的间隔与 \(B\) 走的间隔。
那么考虑从高位到低位贪心,即设当前跳到了 \(s\) 点,若 \(dp1_{s,i} + dp2_{s,i} \le x\),可以从 \(s\) 跳到 \(f_{s,i}\),需要令 \(x \gets x - (dp1_{s,i} + dp2_{s,i})\),然后继续遍历 \(i-1\) 位。
因为是 A 先开车,所以 A 可能会在末了一轮竣事后还能再开上一次,需要特判。
时间复杂度为 \(O((N+Q) \log N)\)。
完整代码:
[code]#include#define Add(x,y) (x+y>=mod)?(x+y-mod)
x+y)#define lowbit(x) x&(-x)#define pi pair#define pii pair#define iip pair#define ppii pair#define fi first#define se second#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x#define Full(a) memset(a,0,sizeof(a))#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);using namespace std;typedef double db;typedef unsigned long long ull;typedef long long ll;bool Begin;const ll N=1e5+10,M=18,INF=1e18;inline ll read(){ ll x=0,f=1; char c=getchar(); while(c'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4