日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

洛谷-P3203 弹飞绵羊 分块

發(fā)布時(shí)間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷-P3203 弹飞绵羊 分块 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目

題目鏈接

題意

據(jù)說(shuō)這道題要用一道叫做LCT的數(shù)據(jù)結(jié)構(gòu),然而我不會(huì)。。。

一排有n個(gè)彈簧裝置,從第ii個(gè)可一往后跳k[i]k[i]步。

  • 修改:修改某個(gè)位置彈簧的彈性。
  • 查詢:詢問(wèn)從某個(gè)位置出發(fā)彈多少次就彈飛了。

題解

分塊首先都要先從暴力開(kāi)始想起:
我們記錄從任意一個(gè)點(diǎn)出發(fā),下一次能跳到哪里,這樣的話我們每次詢問(wèn),只需要一只沿著這條鏈往下走即可,顯然最壞的時(shí)間復(fù)雜度是O(n2)O(n2),修改的時(shí)間復(fù)雜度為O(1)O(1)

優(yōu)化:
讓我們使用分塊來(lái)進(jìn)行優(yōu)化,我們把一條直線上的n個(gè)彈簧進(jìn)行分塊,并對(duì)于每個(gè)彈簧記錄兩個(gè)屬性:sum[i]sum[i]nxtb[i]nxtb[i]。

其中sum[i]sum[i]表示的含義是從ii彈簧出發(fā)在本塊內(nèi)的經(jīng)過(guò)的節(jié)點(diǎn)的個(gè)數(shù),nxtb[i]nxtb[i]表示的是從ii<script type="math/tex" id="MathJax-Element-479">i</script>彈簧出發(fā),彈到下一塊中的第一個(gè)彈簧的編號(hào),彈飛設(shè)置為-1。

這樣的話,詢問(wèn)的時(shí)候我們只需要下面一段代碼就可以了。

int now = x; while(x != -1){ans += sum[now];now = nxtb[now]; }

預(yù)處理的話,我們要倒著往前計(jì)算,因?yàn)榍懊娴膕um用到了后面的sum。
預(yù)處理和修改的話詳情請(qǐng)見(jiàn)代碼。

代碼

#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn = 200007; #define pr(x) cout<<#x<<":"<<x<<endl int Base = 450; int nxtb[maxn]; int val[maxn]; int sum[maxn]; int n,m,op,x,y; inline void read(int &x){scanf(" %d",&x); } int main(){read(n);Base = (int) sqrt(n+0.5);for(int i = 1;i <= n;++i){read(val[i]);}for(int i = n;i >= 1;--i){int j = val[i] + i;int bl = i / Base;int br = j / Base;if(j > n){nxtb[i] = -1;sum[i] = 1;}else if(br == bl){//屬于同一個(gè)塊nxtb[i] = nxtb[j];sum[i] = sum[j]+1;}else{//不屬于同一個(gè)塊nxtb[i] = j;sum[i] = 1;}}read(m);while(m--){read(op);if(op == 1){//詢問(wèn)read(x);x++;int ans = 0;int now = x;while(now != -1){ans += sum[now];now = nxtb[now];}printf("%d\n",ans);}else{//修改read(x);read(y);x++;val[x] = y;int j = x + y;int bl = x / Base;int br = j / Base;if(j > n){sum[x] = 1;nxtb[x] = -1;}else if(bl == br){//屬于用一個(gè)塊sum[x] = sum[j] + 1;nxtb[x] = nxtb[j];}else{//不屬于同一個(gè)塊sum[x] = 1;nxtb[x] = j;}for(int i = x-1;i >= max(1,bl*Base);--i){//更新與x屬于同一塊的可能被x影響的彈簧。j = i + val[i];br = j / Base;if(br == bl){sum[i] = sum[j] + 1;nxtb[i] = nxtb[j];}}}}return 0; }

總結(jié)

以上是生活随笔為你收集整理的洛谷-P3203 弹飞绵羊 分块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。