【BZOJ2683】簡單題 [分治][樹狀數組]

來源:互聯網
上載者:User

標籤:discus   str   執行   problems   blog   owb   des   維護   std   

簡單題Time Limit: 50 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]Description  你有一個N*N的棋盤,每個格子內有一個整數,初始時的時候全部為0,現在需要維護兩種操作:

 

命令

參數限制

內容

1 x y A

1<=x,y<=N,A是正整數

將格子x,y裡的數字加上A

2 x1 y1 x2 y2

1<=x1<= x2<=N

1<=y1<= y2<=N

輸出x1 y1 x2 y2這個矩形內的數字和

3

無

終止程式

Input  輸入檔案第一行一個正整數N。  接下來每行一個操作。Output  對於每個2操作,輸出一個對應的答案。 Sample Input  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  1<=N<=500000,運算元不超過200000個,記憶體限制20M。  對於100%的資料,操作1中的A不超過2000。Solution

  首先把詢問拆成4個,那麼我們就只要維護一個點左下角權值和了。

  然後對所有操作按照 x 升序排序。

  對 y 用個樹狀數組求首碼和,(由於 x 升序,所以此時詢問已經相當於對y求首碼和了)

  以mid為分界線,考慮左區間對右區間的影響。

  顯然,我們可以把左區間的修改執行,然後執行右區間的詢問。

  這樣我們就做完了這道題。

Code
  1 #include<iostream>  2 #include<string>  3 #include<algorithm>  4 #include<cstdio>  5 #include<cstring>  6 #include<cstdlib>  7 #include<cmath>  8 using namespace std;  9 typedef long long s64; 10   11 const int ONE = 1000005; 12 const int INF = 214748340; 13   14 int get() 15 { 16         int res = 1, Q = 1; char c; 17         while( (c = getchar()) < 48 || c > 57) 18             if(c == ‘-‘) Q = -1; 19         if(Q) res = c - 48; 20         while( (c = getchar()) >= 48 && c <= 57) 21             res = res * 10 + c - 48; 22         return res * Q; 23 } 24   25 int n; 26 namespace BIT 27 { 28         int C[ONE]; 29         int lowbit(int i) {return i & -i;} 30         void Add(int R, int x) 31         { 32             for(int i = R; i <= n; i += lowbit(i)) 33                 C[i] += x; 34         } 35         int Query(int R) 36         { 37             int res = 0; 38             for(int i = R; i >= 1; i -= lowbit(i)) 39                 res += C[i]; 40             return res; 41         } 42 } 43   44 int id, query_num, Ans[ONE]; 45 struct power 46 { 47         int id, opt, from; 48         int x, y, val; 49 }oper[ONE], q[ONE]; 50   51 bool cmp(const power &a, const power &b) 52 { 53         if(a.x != b.x) return a.x < b.x; 54         return a.opt < b.opt; 55 } 56   57 void Deal(int x_1, int y_1, int x_2, int y_2) 58 { 59         query_num++; 60         oper[++id] = (power){id, 2, query_num, x_2, y_2, 1}; 61         oper[++id] = (power){id, 2, query_num, x_1 - 1, y_1 - 1, 1}; 62         oper[++id] = (power){id, 2, query_num, x_1 - 1, y_2, -1}; 63         oper[++id] = (power){id, 2, query_num, x_2, y_1 - 1, -1}; 64 } 65   66 void Solve(int l, int r) 67 { 68         if(l >= r) return; 69           70         int mid = l + r >> 1; 71         for(int i = l; i <= r; i++) 72         { 73             if(oper[i].opt == 1 && oper[i].id <= mid) 74                 BIT::Add(oper[i].y, oper[i].val); 75             if(oper[i].opt == 2 && oper[i].id > mid) 76                 Ans[oper[i].from] += BIT::Query(oper[i].y) * oper[i].val; 77         } 78           79         for(int i = l; i <= r; i++) 80             if(oper[i].opt == 1 && oper[i].id <= mid) 81                 BIT::Add(oper[i].y, -oper[i].val); 82           83         int tl = l, tr = mid + 1; 84         for(int i = l; i <= r; i++) 85             if(oper[i].id <= mid) q[tl++] = oper[i]; 86             else q[tr++] = oper[i]; 87           88         for(int i = l; i <= r; i++) 89             oper[i] = q[i]; 90           91         Solve(l, mid), Solve(mid + 1, r); 92 } 93   94 int opt, x_1, y_1, x_2, y_2; 95   96 int main() 97 { 98         n = get(); 99         for(;;)100         {101             opt = get();102             if(opt == 3) break;103             if(opt == 1)104                 oper[++id].id = id, oper[id].opt = 1,105                 oper[id].x = get(), oper[id].y = get(), oper[id].val = get();106             if(opt == 2)107                 x_1 = get(), y_1 = get(),108                 x_2 = get(), y_2 = get(),109                 Deal(x_1, y_1, x_2, y_2);110         }111          112         sort(oper + 1, oper + id + 1, cmp);113          114         Solve(1, id);115          116         for(int i = 1; i <= query_num; i++)117             printf("%d\n", Ans[i]);118 }
View Code

 

【BZOJ2683】簡單題 [分治][樹狀數組]

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.