教主最近學會了一種神奇的魔法,能夠使人長高。於是他準備演示給xmyz資訊組每個英雄看。於是n個英雄們又一次聚集在了一起,這次他們排成了一列,被編號為1、2、……、n。
每個人的身高一開始都是不超過1000的正整數。教主的魔法每次可以把閉區間[l, r](1≤l≤r≤n)內的英雄的身高全部加上乙個整數w。(雖然l=r時並不符合區間的書寫規範,但我們可以認為是單獨增加第l(r)個英雄的身高)
cyz、光哥和zjq等人不信教主的邪,於是他們有時候會問wd閉區間 [l, r] 內有多少英雄身高大於等於c,以驗證教主的魔法是否真的有效。
wd巨懶,於是他把這個回答的任務交給了你。
第1行為兩個整數n、q。q為問題數與教主的施法數總和。
第2行有n個正整數,第i個數代表第i個英雄的身高。
第3到第q+2行每行有乙個操作:
(1) 若第乙個字母為「m」,則緊接著有三個數字l、r、w。表示對閉區間 [l, r] 內所有英雄的身高加上w。
(2) 若第乙個字母為「a」,則緊接著有三個數字l、r、c。詢問閉區間 [l, r] 內有多少英雄的身高大於等於c。
對每個「a」詢問輸出一行,僅含乙個整數,表示閉區間 [l, r] 內身高大於等於c的英雄數。
思路:我們用分塊來寫這道題,分好塊後將塊內的元素排序,然後記錄一下位置,對於修改操作來說,我們可以用直接修改,對於查詢操作的話端點的塊暴力找,中間的由於元素有序,我們可以二分來找,然後計算出該塊的數量,就可以得到答案了
#includeusing namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
struct node
}a[maxn];
ll ad[maxn], id[maxn]; //sum[i]第i塊的和,ad[i]第i塊的增量
ll l[maxn], r[maxn], pos[maxn]; //每段左右端點和每個位置屬於哪一段
int n, m, k; //k個塊
int read()
while(ch >= '0' && ch <= '9')
return x * w;
}ll slove(int l, int r, ll d, ll x) //二分查詢
return pp - r;
}void add(int l, int r, ll d) //區間[l, r]加上d
else
}ll ask(int l, int r, ll d)
else
return ret;
}int main()
if(r[k] < n) //最後有一小塊
for(int i = 1; i <= k; ++i)
}while(m--)
else if(op[0] == 'a')
printf("%lld\n", ask(l, r, d));
}return 0;
}
洛谷P2801 教主的魔法 分塊
題目描述 教主最近學會了一種神奇的魔法,能夠使人長高。於是他準備演示給xmyz資訊組每個英雄看。於是n個英雄們又一次聚集在了一起,這次他們排成了一列,被編號為1 2 n。每個人的身高一開始都是不超過1000的正整數。教主的魔法每次可以把閉區間 l,r 1 l r n 內的英雄的身高全部加上乙個整數w...
P2801 教主的魔法 分塊)
題目傳送 長度為 n n le 1000000 的陣列,q q le 3000 次操作。修改操作即將某個區間的值增加某個不大於1000的值,查詢操作即查詢某個區間比c大於等於的數有多少個 我們用乙個陣列 add i 來表示第 i 段增量,如果查詢區間完全包含第 i 段,那麼就相當於是在原陣列中查詢大...
洛谷P2801 教主的魔法
教主最近學會了一種神奇的魔法,能夠使人長高。於是他準備演示給xmyz資訊組每個英雄看。於是n個英雄們又一次聚集在了一起,這次他們排成了一列,被編號為1 2 n。每個人的身高一開始都是不超過1000的正整數。教主的魔法每次可以把閉區間 l,r 1 l r n 內的英雄的身高全部加上乙個整數w。雖然l ...