洛谷 P2801 教主的魔法 分塊

2021-09-29 14:52:43 字數 1482 閱讀 5967

教主最近學會了一種神奇的魔法,能夠使人長高。於是他準備演示給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 ...