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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU - 1540 Tunnel Warfare(线段树+区间合并)

發布時間:2024/4/11 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU - 1540 Tunnel Warfare(线段树+区间合并) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給定n個村莊,初始化全部連接為一條直線,需要依次執行m個操作,D表示摧毀第i個村莊的連接,R表示恢復最后一

個被摧毀的村莊的連接,Q表示詢問包括本身在內,與第i個村莊相連接的有多少個村莊(間接連接也算)

題目分析:這個題需要用到區間合并的思想,并且用線段樹來實現,應該算是個裸題了,把pushup的板子套進線段樹里就OK,

不過這個題的query函數比較難寫,我會在代碼中寫上相應注釋來幫助理解,其余的函數就都是線段樹的基礎了

上代碼:

#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<sstream> #include<cmath> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=5e4+100;struct Node {int l,r;int ll,rr,all; }tree[N<<2];void build(int k,int l,int r) {tree[k].l=l;tree[k].r=r;tree[k].all=tree[k].ll=tree[k].rr=r-l+1;if(l==r)return;int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r); }void pushup(int k)//注意對三個參數上傳的技巧 {tree[k].ll=tree[k<<1].ll;if(tree[k].ll==tree[k<<1].r-tree[k<<1].l+1)tree[k].ll+=tree[k<<1|1].ll;tree[k].rr=tree[k<<1|1].rr;if(tree[k].rr==tree[k<<1|1].r-tree[k<<1|1].l+1)tree[k].rr+=tree[k<<1].rr;tree[k].all=max(tree[k<<1].rr+tree[k<<1|1].ll,max(tree[k<<1].all,tree[k<<1|1].all));return; }void update(int k,int pos,int val) {if(tree[k].l==tree[k].r){tree[k].all=tree[k].ll=tree[k].rr=val;return;}int mid=(tree[k].r+tree[k].l)>>1;if(mid>=pos)update(k<<1,pos,val);elseupdate(k<<1|1,pos,val);pushup(k); }int query(int k,int pos) {if(tree[k].all==0)return 0;if(tree[k].l+tree[k].ll>pos)//判斷是否在左區間 pos<左端點+左連續return tree[k].ll;if(tree[k].r-tree[k].rr<pos)//判斷是否在右區間 pos>右端點-右連續 return tree[k].rr;if(pos>tree[k<<1].r-tree[k<<1].rr&&pos<tree[k<<1|1].l+tree[k<<1|1].ll)//判斷是否在中間的區間 //右端點-右連續<pos<左端點+左連續return tree[k<<1].rr+tree[k<<1|1].ll;int mid=(tree[k].l+tree[k].r)>>1;if(mid>=pos)//如果上述條件不滿足,繼續向下遞歸判斷return query(k<<1,pos);elsereturn query(k<<1|1,pos); }int main() { // freopen("input.txt","r",stdin);int n,m;while(scanf("%d%d",&n,&m)!=EOF){build(1,1,n);stack<int>st;while(m--){char s[5];scanf("%s",s);if(s[0]=='D'){int num;scanf("%d",&num);st.push(num);update(1,num,0);}else if(s[0]=='R'){if(!st.empty()){update(1,st.top(),1);st.pop();}}else{int num;scanf("%d",&num);cout<<query(1,num)<<endl;}}}return 0; }

?

總結

以上是生活随笔為你收集整理的HDU - 1540 Tunnel Warfare(线段树+区间合并)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。