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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )

發布時間:2023/11/27 生活经验 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

考慮cdq分治, 對于[l, r)遞歸[l, m), [m, r); 然后計算[l, m)的操作對[m, r)中詢問的影響就可以了. 具體就是差分答案+排序+離散化然后樹狀數組維護.操作數為M的話時間復雜度大概是O(M(logM)^2)

-----------------------------------------------------------------------

#include<cstdio>#include<cstring>#include<algorithm>#include<cctype>using namespace std;typedef long long ll;#define cal(x, y) (ll(Val) * (x) * (y))#define lowbit(x) ((x) & -(x))#define h(v) (lower_bound(Y, Y + Yn, v) - Y + 1)#define Q(x) o[Que[x]]#define A(x) o[Ad[x]]const int MAXN = 640009;const int MAXQ = 40009;inline int read() {char c = getchar();int ret = 0, t = 0;for(; !isdigit(c); c = getchar()) if(c == '-') t = 1;for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';return t ? -ret : ret;}int Val, On, Qn;int ans[MAXQ];int Ad[MAXN], Que[MAXQ], Adn, Quen;int Y[MAXN], Yn, X[MAXN], Xn;struct O {int p, x, y, v;inline void Set(int _p, int _x, int _y, int _v) {p = _p; x = _x; y = _y; v = _v;}bool operator < (const O &o) const {return x < o.x;}} o[MAXN + MAXQ];void Init() {Val = read();Qn = On = 0;for(int t = read(); (t = read()) != 3; ) {if(t == 1) {int x = read(), y = read();o[On++].Set(-1, x, y, read());} else {int x0 = read() - 1, y0 = read() - 1, x1 = read(), y1 = read();o[On++].Set(Qn, x0, y0, 1);o[On++].Set(Qn, x1, y1, 1);o[On++].Set(Qn, x0, y1, 0);o[On++].Set(Qn, x1, y0, 0);ans[Qn++] = cal(x0, y0) + cal(x1, y1) - cal(x1, y0) - cal(x0, y1);}}}struct BIT {int b[MAXN];BIT() {memset(b, 0, sizeof b);}void Add(int p, int v) {for(; p <= Yn; p += lowbit(p)) b[p] += v;}int Query(int p) {int ret = 0;for(; p; p -= lowbit(p)) ret += b[p];return ret;}} Bit;bool Cmp(const int &l, const int &r) {return o[l].x < o[r].x;}void Solve() {Yn = Xn = 0;for(int i = 0; i < Quen; i++)Y[Yn++] = Q(i).y, X[Xn++] = Q(i).x;for(int i = 0; i < Adn; i++)Y[Yn++] = A(i).y, X[Xn++] = A(i).x;sort(Que, Que + Quen, Cmp);sort(Ad, Ad + Adn, Cmp);sort(Y, Y + Yn); Yn = unique(Y, Y + Yn) - Y;sort(X, X + Xn); Xn = unique(X, X + Xn) - X;int _Adn = 0, _Quen = 0;for(int i = 0; i < Xn; i++) {while(_Adn < Adn && A(_Adn).x == X[i])Bit.Add(h(A(_Adn).y), A(_Adn).v), _Adn++;while(_Quen < Quen && Q(_Quen).x == X[i]) {int ret = Bit.Query(h(Q(_Quen).y));ans[Q(_Quen).p] += Q(_Quen).v ? ret : -ret;_Quen++;}}for(int i = 0; i < Adn; i++)Bit.Add(h(A(i).y), -A(i).v);}// [l, r)void CDQ(int l, int r) {if(l + 1 >= r) return;int m = (l + r) >> 1;CDQ(l, m); CDQ(m, r);Adn = Quen = 0;for(; l < m; l++)if(!~o[l].p) Ad[Adn++] = l;for(; l < r; l++)if(~o[l].p) Que[Quen++] = l;if(Quen && Adn) Solve();}int main() {Init();CDQ(0, On);for(int i = 0; i < Qn; i++)printf("%d\n", ans[i]);return 0;}

-----------------------------------------------------------------------?

1176: [Balkan2007]Mokia

Time Limit:?30 Sec??Memory Limit:?162 MB
Submit:?1281??Solved:?537
[Submit][Status][Discuss]

Description

維護一個W*W的矩陣,初始值均為S.每次操作可以增加某格子的權值,或詢問某子矩陣的總權值.修改操作數M<=160000,詢問數Q<=10000,W<=2000000.

Input

第一行兩個整數,S,W;其中S為矩陣初始值;W為矩陣大小

接下來每行為一下三種輸入之一(不包含引號):

"1 x y a"

"2 x1 y1 x2 y2"

"3"

輸入1:你需要把(x,y)(第x行第y列)的格子權值增加a

輸入2:你需要求出以左上角為(x1,y1),右下角為(x2,y2)的矩陣內所有格子的權值和,并輸出

輸入3:表示輸入結束

Output

對于每個輸入2,輸出一行,即輸入2的答案

Sample Input

0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3

Sample Output

3
5

HINT

保證答案不會超過int范圍

Source

?

轉載于:https://www.cnblogs.com/JSZX11556/p/5040186.html

總結

以上是生活随笔為你收集整理的BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )的全部內容,希望文章能夠幫你解決所遇到的問題。

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