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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【BZOJ-4631】踩气球 线段树 + STL

發布時間:2023/12/13 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【BZOJ-4631】踩气球 线段树 + STL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

4631: 踩氣球

Time Limit:?10 Sec??Memory Limit:?256 MB
Submit:?224??Solved:?114
[Submit][Status][Discuss]

Description

六一兒童節到了, SHUXK 被迫陪著M個熊孩子玩一個無聊的游戲:有N個盒子從左到右排成一排,第i個盒子里裝著Ai個氣球。 SHUXK 要進行Q次操作,每次從某一個盒子里拿出一個沒被踩爆的氣球,然后熊孩子們就會立刻把它踩爆。 這M個熊孩子每個人都指定了一個盒子區間[Li, Ri]。 如果某一個時刻,一個熊孩子發現自己選定的盒子區間[Li, Ri]中的所有氣球都已經被踩爆了,他就會非常高興(顯然之后他一直會很高興)。 為了不辜負將自己的任務強行塞給 SHUXK 的那個人的期望, SHUXK 想向你詢問:? 他每次操作過后會有多少個熊孩子很高興。

Input

第一行包含兩個正整數N和M,分別表示盒子和熊孩子的個數。 第二行包含N個正整數Ai( 1 < = Ai < = 10^5),表示每個盒子里氣球的數量。 以下M行每行包含兩個正整數Li, Ri( 1 < = Li < = Ri < = N),分別表示每一個熊孩子指定的區間。 以下一行包含一個正整數Q,表示 SHUXK 操作的次數。 以下Q行每行包含一個正整數X,表示這次操作是從第X個盒子里拿氣球。為了體現在線,我們對輸入的X進行了加密。 假設輸入的正整數是x',那么真正的X = (x' + Lastans ? 1)Mod N + 1。其中Lastans為上一次詢問的答案。對于第一個詢問, Lastans = 0。 輸入數據保證1 < = x' < = 10^9, 且第X個盒子中有尚未被踩爆的氣球。 N < = 10^5 ,M < = 10^5 �,Q < = 10^5

Output

包含Q行,每行輸出一個整數,表示 SHUXK 一次操作后詢問的 答案。答案的順序應與輸入數據的順序保持一致。

Sample Input

5 3
1 1 1 1 1
5 5
2 2
1 3
5
4
2
5
2
3

Sample Output

0
1
1
2
3
【樣例說明】
實際上每次操作的盒子是: 4 2 1 3 5
在第二次操作后,第二個熊孩子會高興 (區間[2,2]中的氣球已經全部被踩爆)。
在第四次操作后,第三個熊孩子會高興(區間[1,3]中的氣球已經全部被踩爆)。
在第五次操作后,第一個熊孩子會高興(區間[5,5]中的氣球已經全部被踩爆)。

HINT

Source

Solution

比較好想的一道題

首先對序列建線段樹,把M個區間建到線段樹上,在線段樹的相應節點上記錄

維護區間的A[]值和

修改操作相當于單點-1

當一個區間的和=0時更新這個區間上的熊孩子區間的答案,然后統計ans

期望的時間復雜度大概是$O(MlogN)$

Code

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> using namespace std; inline int read() {int x=0,f=1; char ch=getchar();while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}return x*f; } #define MAXN 100010 int N,M,Q,size[MAXN],ans,last,A[MAXN]; struct SegmentTreeNode{int l,r,sum; vector<int>v; }tree[MAXN<<2]; inline void Update(int now) {tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;} inline void PushUp(int now) {if (tree[now].sum) return;int len=tree[now].v.size(),l=tree[now].l,r=tree[now].r;for (int i=0; i<=len-1; i++)size[ tree[now].v[i] ]-=r-l+1;for (int i=0; i<=len-1; i++)if (!size[ tree[now].v[i] ]) ans++;tree[now].v.clear(); } void BuildTree(int now,int l,int r) {tree[now].l=l; tree[now].r=r;if (l==r) {tree[now].sum=A[l]; return;}int mid=(l+r)>>1;BuildTree(now<<1,l,mid);BuildTree(now<<1|1,mid+1,r);Update(now); PushUp(now); } inline void Change(int now,int pos,int D) {int l=tree[now].l,r=tree[now].r;if (l==r) {tree[now].sum+=D; PushUp(now); return;}int mid=(l+r)>>1;if (pos<=mid) Change(now<<1,pos,D);if (pos>mid) Change(now<<1|1,pos,D);Update(now); PushUp(now); } inline void Cover(int now,int L,int R,int id) {int l=tree[now].l,r=tree[now].r;if (L<=l && R>=r) {tree[now].v.push_back(id); size[id]=R-L+1; return;}int mid=(l+r)>>1;if (L<=mid) Cover(now<<1,L,R,id);if (R>mid) Cover(now<<1|1,L,R,id);Update(now); PushUp(now); } inline int GetX(int x) {return (x+last-1)%N+1;} int main() {N=read(),M=read();for (int i=1; i<=N; i++) A[i]=read();BuildTree(1,1,N);for (int L,R,i=1; i<=M; i++) L=read(),R=read(),Cover(1,L,R,i);Q=read();for (int x,i=1; i<=Q; i++) x=GetX(read()),Change(1,x,-1),printf("%d\n",last=ans);return 0; }

總感覺有種不科學的....畢竟就用了10分鐘就A了...

轉載于:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5793494.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的【BZOJ-4631】踩气球 线段树 + STL的全部內容,希望文章能夠幫你解決所遇到的問題。

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