傳送門
倍增神題????
細節超級多···
其實思路很簡單
對於每個點,a和b要開去的目的地是固定的,所以就想到了倍增
開三個倍增陣列,t[i][j][k]代表k從i開車走2^j天走到的那個城市
f是a走的路程,g是b走的路程
0代表a,1代表b
對於預處理,一開始怎麼想怎麼是n^2的
後來自己yy了一下覺得每次sort一下也行嘛!
look!就像這樣
sort(a+i+1,a+n+1,cmp);
int x=lower_bound(a+i+1,a+n+1,a[i])-a
;if(abs(a[x].h-a[i].h)>abs(a[x-1].h-a[i].h)) x--;
g[i][0][1]=abs(a[x].h-a[i].h); t[i][0][1]=x;
int y;
if(abs(a[x-1].h-a[i].h)<=abs(a[x+1].h-a[i].h)) y=x-1
;else y=x+1
;
外層i從n-1迴圈到1
但是我發現這樣子很容易會找到它自己,好像連樣例2都過不了
於是想到了排序+二分
我覺得這個其實也能過,但寫到一半放棄了覺得一定有更簡單的方法
這時候問了一下小夥伴他們看的是哪個題解(劃掉
然後學習到了一種高階操作(其實很簡單
那就是雙向鍊錶!
sort(a+1,a+n+1);//get到了雙向鍊錶**!
for(int i=1;i<=n;i++) a[i].l=i-1,a[i].r=i+1,pos[a[i].id]=i;
a[1].l=a[n].r=0;
for(int i=1;i<=n;i++)
它可以很方便快捷地解決掉這種有限制性的排序問題
因為每次只能從小往大走,所以找完乙個小的就把它從鍊錶刪掉
這樣找後面的時候一定不會找到它
又因為事先排好了序,所以只要看左邊和右邊哪個更小就好啦!
是不是特別簡單!!!
好了,預處理解決完,就可以開始求倍增陣列了
和lca的套路十分相似,也是根據2次冪,但是要注意1的時候和》1的時候不一樣
所以要單獨考慮一下
求好了倍增陣列,這道題就做完了80%
然而我卻wa在了最後求答案的地方
因為倍增的題只做過lca···
所以十分*****地以為只要貪心地找到第乙個比x0小的就好了
啊我怎麼那麼傻啊喂,有可能還到不了x0啊
給你們看看我的傻**:
for(int i=1;i<=n;i++)
for(int j=17;j>=0;j--)
還有這個:
s=rd(); x
0=rd();
for(int i=17;i>=0;i--)
}
這錯誤思想簡直經典
其實正確寫法應該是這樣:
inline
void
solve(int
s,intx)}
看來基本上所有的倍增都是這麼乙個模板了0.0
說完這些整個題就已經出來了啊喂
這個看似複雜的題就被我們一步一步地解決掉了
其實所有很複雜的題都可以化成簡單的小問題解決的吧qvq
接下來看一下我的ac**!
#include
#include
#include
#include
#include
#define maxn 100005
#define ll long long
using namespace std;
int n,m,s,x
0,t[maxn][20][2],lg;//
0->a 1->b
intpos[maxn],aim,l,r,na[maxn],nb[maxn];
ll g[maxn][20][2],f[maxn][20][2],ans1,ans2,la,lb;//f->a g->b
inline int rd()
while(c<='9' && c>='0') x=x
*10+c-'0',c=getchar();
return
x*f;
}struct qw
qa[maxn];
inline bool cmp1(qwq x,qwq y)
inline bool quq()
inline int qvq(int x,int y)
inline void drive()
sort(a+1,a+n+1,cmp1);
for(int i=n-1;i;i--)
t[i][1][0]=t[y][0][1]; f[i][1][0]=f[i][0][0]; f[i][1][1]=f[x][0][0];
t[i][1][1]=t[x][0][0]; g[i][1][0]=g[y][0][1]; g[i][1][1]=g[i][0][1];
}for(int j=2;j<=lg;j++)
for(int i=1;i<=n;i++)
for(int k=0;k<=1;k++)
}inline void solve(int
s,intx)}
int main()
printf("%d\n",aim);
m=rd();
while(m--)
return
0;}
luogu1081 開車旅行
這個題目還是值得思考的.看到這個題目,大家應該都想到了這樣乙個思路,就是把每個點能夠達到的最近的和次近的點都預處理出來,然後跑就可以了,現在問題就是難在這個預處理上面,我們應該如何做呢?觀察到,近的概念是兩點之間的海拔距離最小,所以我們可以將海拔距離從後往前 畢竟你只能往你後面的地方走嘛.扔進乙個可...
Luogu1081 開車旅行
巨長的倍增題.顯然這是沒有什麼決策的,選擇方案都是固定的 這可以考慮倍增跳,每個位置上跳到的位置是可以通過查前驅後繼解決的 有兩種方式 一種是平衡樹搞法,倒著做查完了插入 另一種是先排序建乙個鍊錶,查完了刪除 都是可以通過加哨兵節點來搞的,結果我只想到了 set 亂搞,就寫了很長 預處理完就可做了 ...
P1081 開車旅行 倍增 (毒瘤題)
其實就是個大模擬。首先,根據題意,小a和小b從任意乙個城市開始走,無論 x 如何,其路徑是一定唯一的。顯然對於兩問都可以想出乙個 o n 2 的暴力,即直接一步一步地向右走。首先,我們當然需要知道a,b在每個城市的下一步如何走,記 nexta i nextb i 為a,b在 i 處時,下一步走到的城...