題目傳送門:
題目分析:這題的兩個問其實是差不多的。第一問給出了x0,我們列舉起點s,就相當於變成了n個第二類詢問(s
,x0)
(1<=
s<=n)
。於是現在原問題變成了:給出(s,x),如何快速求s開始往下走不超過x距離時,a,b各走的距離?然後用資料結構預處理出a,b到達每乙個點之後會走哪個點,詢問時倍增往後跳統計答案即可。調**的時候注意a可能比b多走一步的情況,以及a,b走的距離均為0的情況。
code:
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn=100100;
const
int maxl=22;
const
long
long m1=998244353;
const
long
long m2=1000000007;
const
long
long m3=1333333331;
typedef
long
long ll;
struct tnode
tree[maxn];
tnode *root=null;
int cur=-1;
int next1[maxn];
int next2[maxn];
int next[maxn][maxl];
ll disa[maxn][maxl];
ll disb[maxn][maxl];
int a[maxn];
int n,m;
ll seed,x0;
ll suma,sumb;
int rand()
tnode *new_node(int v)
void right_turn(tnode *&p)
void left_turn(tnode *&p)
void insert(tnode *&p,int v)
else
}int get_prev(tnode *p,int x,int v)
int get_succ(tnode *p,int x,int v)
int abs(int x)
void work(int s,int x)
if ( next2[s] && abs(a[ next2[s] ]-a[s])<=left) suma+=abs(a[ next2[s] ]-a[s]);
}int main()
else
}//for (int i=1; i<=n; i++) printf("%d %d\n",next1[i],next2[i]);
for (int i=1; i<=n; i++)
}for (int j=1; jfor (int i=1; i<=n; i++)
}//for (int i=1; i<=n; i++) printf("%d\n",next[i][0]);
scanf("%lld",&x0);
int ans=0;
ll ansa=m1,ansb=-1;
for (int s=1; s<=n; s++)}}
printf("%d\n",ans);
scanf("%d",&m);
for (int i=1; i<=m; i++)
return
0;}
洛谷 P1081 開車旅行
題目描述 小 a 和小 b 決定利用假期外出旅行,他們將想去的城市從 1 到 n 編號,且編號較小的城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為hi,城市 i 和城市 j 之間的距離 d i,j 恰好是這兩個城市海拔高度之差的絕對值,即d i,j hi hj ...
P1081 開車旅行
p1081 開車旅行 排序優化 倍增 其實這道題一開始是一點也沒有頭緒,知道有高人指點了一下。說並不需要拘束於出發點和路徑長度,也就是問題1.2。不過乙個是固定路徑長度的詢問,另乙個是給定起點和路徑長度的詢問。所以問題一和問題二是可以使用乙個函式解決的,而且對於乙個城市來說,在不考慮路程的情況下,路...
P1081 開車旅行
傳送門 用倍增的思想 設 a i 表示a在 i 位置走一步到達的城市以及經過的路程 這裡我用結構體存a i b同理 設 f i j 表示從 i 位置出發,走 2 j 輪後到達的城市 一輪即ab各走一次 dis i j 表示從 i 位置出發,走 2 j 輪後經過總路程 da i j 表示從 i 位置出...