fork download
  1. //#pragma GCC optimize("Ofast,unroll-loops")
  2. //#pragma GCC target("avx2,tune=native")
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5.  
  6. #define file "o"
  7. #define ff(i, a, b) for (auto i=(a); i<=(b); ++i)
  8. #define ffr(i, b, a) for (auto i=(b); i>=(a); --i)
  9. #define nl "\n"
  10. #define ss " "
  11. #define pb emplace_back
  12. #define fi first
  13. #define se second
  14. #define sz(s) (int)s.size()
  15. #define all(s) (s).begin(), (s).end()
  16. #define ms(a,x) memset(a, x, sizeof (a))
  17. #define cn continue
  18. #define re exit(0)
  19.  
  20. typedef long long ll;
  21. typedef unsigned long long ull;
  22. typedef long double ld;
  23. typedef vector<int> vi;
  24. typedef vector<ll> vll;
  25. typedef pair<int,int> pii;
  26. typedef pair<ll,ll> pll;
  27. typedef vector<pii> vpii;
  28. typedef vector<pll> vpll;
  29.  
  30. mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
  31. ll ran(ll l, ll r) { return uniform_int_distribution<ll>(l, r)(rng); }
  32.  
  33. inline void rf() {
  34. ios_base::sync_with_stdio(false);
  35. cin.tie(nullptr); cout.tie(nullptr);
  36. if (fopen(file".inp","r")) {
  37. freopen(file".inp","r",stdin);
  38. freopen(file".out","w",stdout);
  39. }
  40. }
  41.  
  42. const int mod = 1e9+7;
  43.  
  44. struct Upd {
  45. int xa, ya, xb, yb, t;
  46. ll w;
  47. };
  48.  
  49. int main() {
  50. rf();
  51.  
  52. int K, P;
  53. if(!(cin >> K >> P)) return 0;
  54.  
  55. vector<Upd> ups(P);
  56. int maxT = 0;
  57.  
  58. // Tổng năng lượng S bằng hiệu 2D toàn cục
  59. vector<vector<ll>> D(K+3, vector<ll>(K+3, 0));
  60.  
  61. ff(i,0,P-1){
  62. int xa, ya, xb, yb, t; ll w;
  63. cin >> xa >> ya >> xb >> yb >> t >> w;
  64. if(xa>xb) swap(xa,xb);
  65. if(ya>yb) swap(ya,yb);
  66. ups[i] = {xa,ya,xb,yb,t,w};
  67. maxT = max(maxT, t);
  68.  
  69. // Cập nhật tổng S (không phân biệt kênh)
  70. D[xa][ya] += w;
  71. D[xb+1][ya] -= w;
  72. D[xa][yb+1] -= w;
  73. D[xb+1][yb+1] += w;
  74. }
  75.  
  76. // Prefix 2D -> S
  77. vector<vector<ll>> S(K+2, vector<ll>(K+2,0));
  78. ff(x,1,K){
  79. ll run=0;
  80. ff(y,1,K){
  81. run += D[x][y];
  82. S[x][y] = S[x-1][y] + run;
  83. }
  84. }
  85.  
  86. // Gom chỉ số update theo kênh để xác minh nhanh
  87. vector<vector<int>> byT(maxT+1);
  88. ff(i,0,P-1) byT[ups[i].t].push_back(i);
  89.  
  90. // Chia khối
  91. const int B = 32; // 32~40 là ổn
  92. int BX = (K + B - 1) / B, BY = (K + B - 1) / B;
  93.  
  94. struct BlockInfo {
  95. int cand = 0; // ứng viên Boyer–Moore
  96. ll bal = 0; // cân bằng
  97. vector<int> border; // danh sách update cắt biên khối
  98. };
  99. vector<vector<BlockInfo>> blk(BX, vector<BlockInfo>(BY));
  100.  
  101. auto blockBounds = [&](int bx, int by) {
  102. int xl = bx*B + 1, xr = min(K, (bx+1)*B);
  103. int yl = by*B + 1, yr = min(K, (by+1)*B);
  104. return array<int,4>{xl,yl,xr,yr};
  105. };
  106.  
  107. auto fullyCover = [&](const Upd& u, int bx, int by)->bool{
  108. auto b = blockBounds(bx,by);
  109. return (u.xa <= b[0] && b[2] <= u.xb && u.ya <= b[1] && b[3] <= u.yb);
  110. };
  111.  
  112. auto overlap = [&](const Upd& u, int bx, int by)->bool{
  113. auto b = blockBounds(bx,by);
  114. if (u.xa > b[2] || u.xb < b[0] || u.ya > b[3] || u.yb < b[1]) return false;
  115. return true;
  116. };
  117.  
  118. // Boyer–Moore theo khối + gom border
  119. for(int i=0;i<P;++i){
  120. const auto &u = ups[i];
  121. int bx1 = (u.xa-1)/B, bx2 = (u.xb-1)/B;
  122. int by1 = (u.ya-1)/B, by2 = (u.yb-1)/B;
  123.  
  124. for(int bx=bx1; bx<=bx2; ++bx){
  125. for(int by=by1; by<=by2; ++by){
  126. if(fullyCover(u,bx,by)){
  127. auto &bi = blk[bx][by];
  128. if(bi.cand==u.t){ bi.bal += u.w; }
  129. else{
  130. if(bi.bal >= u.w) bi.bal -= u.w;
  131. else { bi.cand = u.t; bi.bal = u.w - bi.bal; }
  132. }
  133. }else if(overlap(u,bx,by)){
  134. blk[bx][by].border.push_back(i);
  135. }
  136. }
  137. }
  138. }
  139.  
  140. // Kết quả
  141. vector<vector<int>> ans(K+1, vector<int>(K+1, 0));
  142.  
  143. // Xác minh cho từng khối
  144. for(int bx=0; bx<BX; ++bx){
  145. for(int by=0; by<BY; ++by){
  146. auto b = blockBounds(bx,by);
  147. int xl=b[0], yl=b[1], xr=b[2], yr=b[3];
  148. int nx = xr-xl+1, ny = yr-yl+1;
  149.  
  150. // Tập kênh cần kiểm tra
  151. vector<int> candList;
  152. {
  153. unordered_set<int> seen;
  154. if(blk[bx][by].cand) { seen.insert(blk[bx][by].cand); candList.push_back(blk[bx][by].cand); }
  155. for(int id: blk[bx][by].border){
  156. int t = ups[id].t;
  157. if(!seen.count(t)){ seen.insert(t); candList.push_back(t); }
  158. }
  159. }
  160.  
  161. // Nếu không có ứng viên nào (rất hiếm) → chắc chắn 0
  162. if(candList.empty()){
  163. ff(x,xl,xr) ff(y,yl,yr) ans[x][y]=0;
  164. continue;
  165. }
  166.  
  167. // Với mỗi kênh ứng viên, tính năng lượng trong khối bằng hiệu 2D cục bộ và kiểm tra
  168. // Nếu tìm được kênh thắng, gán ngay (không thể có 2 kênh > 1/2).
  169. // Đầu tiên, mặc định là 0
  170. ff(x,xl,xr) ff(y,yl,yr) ans[x][y]=0;
  171.  
  172. for(int t : candList){
  173. // diff cục bộ
  174. vector<vector<ll>> Dloc(nx+2, vector<ll>(ny+2, 0));
  175. ll baseAll = 0;
  176.  
  177. // duyệt tất cả update của kênh t
  178. for(int id : byT[t]){
  179. const auto &u = ups[id];
  180. if(u.xa>xr || u.xb<xl || u.ya>yr || u.yb<yl) continue; // không giao
  181.  
  182. if(u.xa<=xl && xr<=u.xb && u.ya<=yl && yr<=u.yb){
  183. // phủ trọn khối
  184. baseAll += u.w;
  185. }else{
  186. // giao cục bộ
  187. int xa=max(u.xa,xl), xb=min(u.xb,xr);
  188. int ya=max(u.ya,yl), yb=min(u.yb,yr);
  189. // chuyển sang chỉ số 1..nx,1..ny
  190. int x1=xa-xl+1, x2=xb-xl+1;
  191. int y1=ya-yl+1, y2=yb-yl+1;
  192. Dloc[x1][y1] += u.w;
  193. Dloc[x2+1][y1] -= u.w;
  194. Dloc[x1][y2+1] -= u.w;
  195. Dloc[x2+1][y2+1] += u.w;
  196. }
  197. }
  198.  
  199. // Prefix cục bộ và kiểm tra điều kiện > 1/2
  200. // Nếu ô nào đã có đáp án khác 0 thì bỏ qua (đã xác định kênh thắng)
  201. for(int i=1;i<=nx;++i){
  202. ll run=0;
  203. for(int j=1;j<=ny;++j){
  204. run += Dloc[i][j];
  205. ll Ec = baseAll + ( (i>1?Dloc[i-1][j]:0) + run ); // Sai! cần prefix 2D chuẩn
  206. }
  207. }
  208. // prefix 2D chuẩn:
  209. for(int i=1;i<=nx;++i){
  210. for(int j=1;j<=ny;++j){
  211. Dloc[i][j] += Dloc[i-1][j] + Dloc[i][j-1] - Dloc[i-1][j-1];
  212. }
  213. }
  214. bool anySet = false;
  215. for(int i=1;i<=nx;++i){
  216. for(int j=1;j<=ny;++j){
  217. int x = xl + i - 1;
  218. int y = yl + j - 1;
  219. if(ans[x][y]) continue; // đã có kênh thắng
  220. ll Ec = baseAll + Dloc[i][j];
  221. if( Ec*2 > S[x][y] ){
  222. ans[x][y] = t;
  223. anySet = true;
  224. }
  225. }
  226. }
  227. // tối ưu nhỏ: nếu tất cả đã gán xong (không có ô nào còn 0 mà có thể được kênh khác thắng >1/2) thì có thể tiếp,
  228. // nhưng để an toàn ta vẫn thử các ứng viên còn lại.
  229. }
  230. }
  231. }
  232.  
  233. // In ra K dòng, mỗi dòng K số
  234. ff(x,1,K){
  235. ff(y,1,K){
  236. if(y>1) cout << ' ';
  237. cout << ans[x][y];
  238. }
  239. cout << '\n';
  240. }
  241. return 0;
  242. }
  243.  
Success #stdin #stdout 0.01s 5320KB
stdin
5 3
1 3 5 5 1 3
1 1 3 5 2 3
2 2 4 4 2 5
stdout
2 2 0 0 0
2 2 2 2 0
2 2 2 2 0
0 2 2 2 1
0 0 1 1 1