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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ 4066: 简单题

發布時間:2025/3/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 4066: 简单题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

4066: 簡單題

Time Limit:?50 Sec??Memory Limit:?20 MB
Submit:?2373??Solved:?622
[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。 接下來每行一個操作。每條命令除第一個數字之外, 均要異或上一次輸出的答案last_ans,初始時last_ans=0。

?

Output

對于每個2操作,輸出一個對應的答案。

?

Sample Input

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

Sample Output

3
5

HINT

?

數據規模和約定
1<=N<=500000,操作數不超過200000個,內存限制20M,保證答案在int范圍內并且解碼之后數據仍合法。
樣例解釋見OJ2683

新加數據一組,但未重測----2015.05.24

?

?

Source

By wjy1998

[Submit][Status][Discuss]

?

記得BZOJ還有兩道題和這個題是一個意思,但是略有不同。

?

這道題有兩個地方需要注意:

1. 數據通過一定方式強制在線

2. 內存限制只有20M,二維數據結構基本被終結

?

顯然是KD-Tree了,而且需要定期重建以保持其優秀的性質。看到有的題解沒有重建就AC了,大概新加數據有卡這類程序,亦或者是大佬的KD-Tree十分優美吧,我等蒟蒻并無此功底……

?

因為數據以3作為輸入終止信號,一開始并不知道有多少操作,也不知道操作是什么,我也懶得先存起來統計操作次數,所以需要找一個合適的重建限度,及進行多少次插入操作后,重建整個KD-Tree。要來數據在本地試了幾個數字,發現這個限度取1500~2000較為合適(我一開始猜了個500,直接TLE了),雖然OJ和本地的測試環境有些差距吧,但還是可以作為參考,小伙伴可以像我一樣取1700,OJ上跑了30S。

?

1 #include <cstdio> 2 #include <algorithm> 3 4 inline int getint(void) 5 { 6 int r = 0, f = 0, c = getchar(); 7 8 for (; c < 48; c = getchar()) 9 if (c == '-')f ^= 1; 10 11 for (; c > 47; c = getchar()) 12 r = r * 10 + c - 48; 13 14 return f ? -r : r; 15 } 16 17 const int siz = 200005; 18 19 struct node 20 { 21 int val; 22 int sum; 23 int pos[2]; 24 int son[2]; 25 int mini[2]; 26 int maxi[2]; 27 28 inline void setup(int x, int y, int v) 29 { 30 val = sum = v; 31 son[0] = son[1] = 0; 32 pos[0] = mini[0] = maxi[0] = x; 33 pos[1] = mini[1] = maxi[1] = y; 34 } 35 }tr[siz]; int tot; 36 37 inline void update(int t) 38 { 39 tr[t].sum = tr[t].val; 40 41 if (tr[t].son[0]) 42 tr[t].sum += tr[tr[t].son[0]].sum; 43 if (tr[t].son[1]) 44 tr[t].sum += tr[tr[t].son[1]].sum; 45 46 tr[t].mini[0] = tr[t].maxi[0] = tr[t].pos[0]; 47 tr[t].mini[1] = tr[t].maxi[1] = tr[t].pos[1]; 48 49 for (int i = 0; i < 2; ++i)if (tr[t].son[i]) 50 for (int j = 0; j < 2; ++j) 51 { 52 if (tr[t].mini[j] > tr[tr[t].son[i]].mini[j]) 53 tr[t].mini[j] = tr[tr[t].son[i]].mini[j]; 54 if (tr[t].maxi[j] < tr[tr[t].son[i]].maxi[j]) 55 tr[t].maxi[j] = tr[tr[t].son[i]].maxi[j]; 56 } 57 } 58 59 void insert(int &t, int p, int k) 60 { 61 if (!t)t = p; 62 else 63 { 64 if (tr[p].pos[k] <= tr[t].pos[k]) 65 insert(tr[t].son[0], p, k ^ 1); 66 else 67 insert(tr[t].son[1], p, k ^ 1); 68 69 update(t); 70 } 71 } 72 73 int cmpk; 74 75 inline bool cmp(const node &a, const node &b) 76 { 77 if (a.pos[cmpk] != b.pos[cmpk]) 78 return a.pos[cmpk] < b.pos[cmpk]; 79 else 80 return a.pos[cmpk^1] < b.pos[cmpk^1]; 81 } 82 83 int build(int l, int r, int k) 84 { 85 int mid = (l + r) >> 1; cmpk = k; 86 87 std::nth_element(tr + l, tr + mid, tr + r + 1, cmp); 88 89 tr[mid].son[0] = l < mid ? build(l, mid - 1, k ^ 1) : 0; 90 tr[mid].son[1] = r > mid ? build(mid + 1, r, k ^ 1) : 0; 91 92 return update(mid), mid; 93 } 94 95 int x1, y1, x2, y2, ans; 96 97 inline bool none(int t) 98 { 99 return 100 x1 > tr[t].maxi[0] 101 || x2 < tr[t].mini[0] 102 || y1 > tr[t].maxi[1] 103 || y2 < tr[t].mini[1]; 104 } 105 106 inline bool have(int t) 107 { 108 return 109 x1 <= tr[t].mini[0] 110 && x2 >= tr[t].maxi[0] 111 && y1 <= tr[t].mini[1] 112 && y2 >= tr[t].maxi[1]; 113 } 114 115 inline bool in(int t) 116 { 117 return 118 x1 <= tr[t].pos[0] 119 && x2 >= tr[t].pos[0] 120 && y1 <= tr[t].pos[1] 121 && y2 >= tr[t].pos[1]; 122 } 123 124 void query(int t) 125 { 126 if (none(t))return; 127 if (have(t))ans += tr[t].sum; 128 else 129 { 130 if (in(t))ans += tr[t].val; 131 if (tr[t].son[0])query(tr[t].son[0]); 132 if (tr[t].son[1])query(tr[t].son[1]); 133 } 134 } 135 136 signed main(void) 137 { 138 // freopen("simple.in", "r", stdin); 139 // freopen("simple.out", "w", stdout); 140 141 int n = getint(), root = ++tot; 142 143 tr[root].setup(n >> 1, n >> 1, 0); 144 145 while (true) 146 { 147 int k = getint(); 148 149 if (k == 1) 150 { 151 int x = getint() ^ ans; 152 int y = getint() ^ ans; 153 int v = getint() ^ ans; 154 155 tr[++tot].setup(x, y, v); 156 157 if (tot % 1700) 158 insert(root, tot, 0); 159 else 160 root = build(1, tot, 0); 161 } 162 else if (k == 2) 163 { 164 x1 = getint() ^ ans; 165 y1 = getint() ^ ans; 166 x2 = getint() ^ ans; 167 y2 = getint() ^ ans; 168 169 ans = 0; query(root); 170 171 printf("%d\n", ans); 172 } 173 else break; 174 } 175 176 // fclose(stdin); 177 // fclose(stdout); 178 } 179 180 /* 181 2000 : 18.02 182 1800 : 17.22 183 1700 : 16.89 184 1500 : 17.74 185 1000 : 20.80 186 900 : 22.53 187 700 : 25.08 188 500 : 33.55 189 300 : T L E 190 */

?

@Author: YouSiki

轉載于:https://www.cnblogs.com/yousiki/p/6285500.html

總結

以上是生活随笔為你收集整理的BZOJ 4066: 简单题的全部內容,希望文章能夠幫你解決所遇到的問題。

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