description這道題貌似有很多解法,那我就說說我的做法吧.六一兒童節到了, shuxk 被迫陪著m個熊孩子玩乙個無聊的遊戲:有n個盒子從左到右排成一排,第i個盒子裡裝著ai個氣球。
shuxk 要進行q次操作,每次從某乙個盒子裡拿出乙個沒被踩爆的氣球,然後熊孩子們就會立刻把它踩爆。
這m個熊孩子每個人都指定了乙個盒子區間[li, ri]。 如果某乙個時刻,乙個熊孩子發現自己選定的盒子區間[li, ri]中的所
有氣球都已經被踩爆了,他就會非常高興(顯然之後他一直會很高興)。
為了不辜負將自己的任務強行塞給 shuxk 的那個人的期望, shuxk 想向你詢問:
他每次操作過後會有多少個熊孩子很高興。
input
包含q行,每行輸出乙個整數,表示 shuxk 一次操作後詢問的
答案的順序應與輸入資料的順序保持一致。
首先用一維陣列把問題簡化.
然後就是每次操作之後求有多少的區間變成了全部為0的區間
但是我們發現有很多區間都要進行詢問,我們不可能遍歷所有區間去查詢
所以我們考慮每次修改單點會對哪些區間造成影響
一次修改會對線段樹上的logn的區間造成影響,所以我們看有多少詢問區間覆蓋了這個區間
也就是吧詢問區間拆成線段樹的多個區間組合,發現最多也是logn的
所以用鍊錶維護乙個線段樹區間上表示的詢問區間即可。
感覺這個做法挺簡單的,不用高階資料結構
#include #include #include using namespace std;
typedef long long ll;
inline void read(int &x)
const int maxn = 100010;
struct nodeg[maxn*20];
int head[maxn<<2],cnt;
inline void add(int u,int v)
int t[maxn<<2],num[maxn],a[maxn];
inline void build(int rt,int l,int r)
int mid = l+r >> 1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
t[rt] = t[rt<<1] + t[rt<<1|1];
}inline void insert(int rt,int l,int r,int l,int r,int nw)
int mid = l+r >> 1;
if(l <= mid) insert(rt<<1,l,mid,l,r,nw);
if(r > mid) insert(rt<<1|1,mid+1,r,l,r,nw);
}int ans = 0;
inline void set(int u)head[u] = 0;
}inline void modify(int rt,int l,int r,int pos)
int mid = l+r >> 1;
if(pos <= mid) modify(rt<<1,l,mid,pos);
else modify(rt<<1|1,mid+1,r,pos);
t[rt] = t[rt<<1] + t[rt<<1|1];
if(t[rt] == 0) set(rt);
}int main()
int q;read(q);
while(q--)
getchar();getchar();
return 0;
}
BZOJ4631 踩氣球 題解(線段樹)
題目鏈結 題目大意 給定乙個長度為 n 的序列 現在有 m 個區間 l i,r i 和 q 個操作,每次選取乙個 x 使得 a x 問每一次操作後區間和為 0 的區間個數。可以用主席樹解決,但蒟蒻不會,蒟蒻只會寫線段樹qaq。對於每乙個區間 l i,r i 我們可以把它分解成線段樹上 s 個區間,線...
bzoj 4631 踩氣球 線段樹合併
time limit 10 sec memory limit 256 mb submit 265 solved 136 submit status discuss 六一兒童節到了,shuxk 被迫陪著m個熊孩子玩乙個無聊的遊戲 有n個盒子從左到右排成一排,第i個盒子裡裝著ai個氣球。shuxk 要進...
BZOJ 4756 線段樹合併(線段樹)
思路 1.最裸的線段樹合併 2.我們可以觀察到子樹求乙個東西 那我們直接dfs序好了 入隊的時候統計一下有多少比他大的 出的時候統計一下 減一下 搞定 線段樹合併 by siriusren include include include using namespace std const int n...