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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

H - Tunnel Warfare HDU - 1540

發(fā)布時間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 H - Tunnel Warfare HDU - 1540 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

H - Tunnel Warfare HDU - 1540

題意:

n個數(shù)順序排列,左右數(shù)相連,
現(xiàn)在有三個操作:
1.摧毀一個位置上的數(shù)
2.回復(fù)上一次摧毀的數(shù)
3.查詢包含該位置的最長連續(xù)區(qū)間長度

題解:

有兩個方法,第一個是區(qū)間的最大值-最小值-1,這個就不講了
第二個方法是區(qū)間合并更新答案
參考文章
利用線段樹 求出每個線段左端點(diǎn)長度lsum(自左端點(diǎn)向右的連續(xù)長度),右端點(diǎn)長度rsum(自右端點(diǎn)向左連續(xù)長度) 以及區(qū)間內(nèi)最長連續(xù)長度sum(以為可能存在一個連續(xù)長度既不包含左端點(diǎn)也不包含右端點(diǎn))
破壞和修復(fù)的區(qū)別其實(shí)就是lsum,rsum,sum的值
我們用一個函數(shù)來求,1表示存在,0表示被破壞
詳細(xì)講講過程:
如果區(qū)間合并更新答案?
我們已經(jīng)定義了lsum,rsum,和sum
我們更新lsum,rsum,然后用來更新sum
如果左子樹滿了,root的lsum的長度就等于左子樹(root<<1)的長度加上右子樹(root<<1|1)的lsum

右子樹同理
最長區(qū)間是三部分取最大值
1.左子樹從左端點(diǎn)開始的最長連續(xù)區(qū)間
2.右子樹從右端點(diǎn)開始的最長連續(xù)區(qū)間
(上面這倆就是剛才講的更新)
3.左子樹的右端點(diǎn)向左+右子樹的左端點(diǎn)向右 (如圖)

更新時就將lsum,rsum,sum更新為所指坐標(biāo),如果是摧毀就賦值為0
查詢就是找點(diǎn)在哪個區(qū)間,輸出答案就行

代碼:

#include <iostream> #include <bits/stdc++.h> using namespace std;const int maxn = 50005;struct node {int L, R, lsum, rsum, sum;//左端點(diǎn)長度lsum(自左端點(diǎn)向右的連續(xù)長度)//區(qū)間內(nèi)最長連續(xù)長度int Mid() {return (L+R)/2;}int Len() {return (R-L+1);} }a[maxn*4]; void pushup(int p) {a[p].lsum = a[p << 1].lsum;a[p].rsum = a[p << 1|1].rsum;if (a[p << 1].lsum == a[p << 1].Len())//左子樹滿 a[p].lsum = a[p << 1].Len()+a[p << 1|1].lsum;if (a[p << 1|1].rsum == a[p << 1|1].Len())//右子樹滿 a[p].rsum =a[p << 1|1].Len()+a[p << 1].rsum;/*然后是三部分取最大值1.左子樹從左端點(diǎn)開始的最長連續(xù)區(qū)間2.右子樹從右端點(diǎn)開始的最長連續(xù)區(qū)間3.左子樹的右端點(diǎn)向左+右子樹的左端點(diǎn)向右 */int len=a[p<<1].rsum+a[p<<1|1].lsum;a[p].sum = max(a[p].lsum, max(a[p].rsum, len)); }void Build(int p, int l, int r) {a[p].L = l;a[p].R = r;a[p].lsum = a[p].rsum = a[p].sum = a[p].Len();if (l == r) return;Build(p << 1, l, a[p].Mid());Build(p << 1|1, a[p].Mid()+1, r); }void Insert(int p, int k, int x) {if (a[p].L == a[p].R) {a[p].lsum = a[p].rsum = a[p].sum = x;return;}if (k <= a[p].Mid())Insert(p << 1, k, x);elseInsert(p << 1|1, k, x);pushup(p); }int Query(int p, int k) {if (a[p].sum == 0) return 0;//先查看k是否被左右倆個區(qū)間包括在內(nèi) if (k < a[p].L+a[p].lsum) return a[p].lsum;if (k > a[p].R-a[p].rsum) return a[p].rsum;//然后查看左子樹有部分+右子樹左部分 if (k > a[p << 1].R-a[p << 1].rsum&&k < a[p << 1|1].L+a[p << 1|1].lsum)return a[p << 1].rsum+a[p << 1|1].lsum;if (k <= a[p].Mid())return Query(p << 1, k);elsereturn Query(p << 1|1, k); } int main() {int n, m;while (~scanf("%d%d", &n, &m)) {int x;char s[10];stack <int> sta;Build(1, 1, n);while (m--) {scanf("%s", s);if (s[0] == 'D') {scanf("%d", &x);Insert(1, x, 0);sta.push(x);} else if (s[0] == 'R'&&sta.size()) {Insert(1, sta.top(), 1);sta.pop();} else if (s[0] == 'Q') {scanf("%d", &x);printf("%d\n", Query(1, x));}}}return 0; }

總結(jié)

以上是生活随笔為你收集整理的H - Tunnel Warfare HDU - 1540的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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