Https://vijos.org/p/1750
Is it complicated ....
I YY a two-dimensional line segment tree and beat it happily.
But wa has two methods ....... Sad
The reason is that there is a small problem in processing the second-dimensional update, sad.
Void pushup1 (int x) {for1 (I, 1, mm <2) Mn [x] [I] = min (Mn [LC] [I], mn [RC] [I]);}
Mm * 4... I should think about it .. This is a problem found during dbg. Sad.
I think it is strange that there are a total of MM nodes at the bottom layer of the Line Segment tree. Isn't the whole tree a mm * 2-1 node. Why do we need to drive to * 4 .... Ask for advice ..
Obviously, we enumerate each vertex and maintain the minimum value of the matrix. Then we can just prefix and cut it out.
The maintenance matrix uses the line segment tree to set the line segment tree, log ^ 2n, and the time is touching to 5000 Ms .... Sad .. That is, maintain row intervals and column intervals.
I wrote it for the first time, and it was my own yy. I don't know if there will be any constant optimization?
I also heard that this question is a monotonous queue? What?
The line segment tree can be built by myself. I won't talk about it .. No. You can check the code.
Run Longlong for calculation.
Then, when selecting a node, the mark is actually very simple. You only need to consider whether the four points have been removed. The reason is very simple ......... Think about it.
#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <iostream>#include <algorithm>#include <queue>using namespace std;#define rep(i, n) for(int i=0; i<(n); ++i)#define for1(i,a,n) for(int i=(a);i<=(n);++i)#define for2(i,a,n) for(int i=(a);i<(n);++i)#define for3(i,a,n) for(int i=(a);i>=(n);--i)#define for4(i,a,n) for(int i=(a);i>(n);--i)#define CC(i,a) memset(i,a,sizeof(i))#define read(a) a=getint()#define print(a) printf("%d", a)#define dbg(x) cout << (#x) << " = " << (x) << endl#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }#define printarr1(a, b) for1(_, 1, b) cout << a[_] << ‘\t‘; cout << endlinline const int getint() { int r=0, k=1; char c=getchar(); for(; c<‘0‘||c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘&&c<=‘9‘; c=getchar()) r=r*10+c-‘0‘; return k*r; }inline const int max(const int &a, const int &b) { return a>b?a:b; }inline const int min(const int &a, const int &b) { return a<b?a:b; }#define lc x<<1#define rc x<<1|1#define lson l, m, lc#define rson m+1, r, rc#define MID (l+r)>>1typedef long long ll;const int N=1005, oo=0x7f7f7f7f;struct dat { int x, y; ll d; }home[N*N], ans[N*N];bool cmp(const dat &a, const dat &b) {if(a.d==b.d) {if(a.x==b.x) return a.y<b.y;return a.x<b.x;}return a.d<b.d;}int mn[N<<2][N<<2], a[N][N], A, B, cnt, ct, nn, mm;bool vis[N][N];ll sum[N][N];void pushup1(int x) { for1(i, 1, mm<<2) mn[x][i]=min(mn[lc][i], mn[rc][i]); }void pushup2(int *s, int x) { s[x]=min(s[lc], s[rc]); }void build2(int l, int r, int x, int *s, int row) {if(l==r) { s[x]=a[row][l]; return; }int m=MID;build2(lson, s, row); build2(rson, s, row);pushup2(s, x);}void build1(int l, int r, int x) {if(l==r) { build2(1, mm, 1, mn[x], l); return; }int m=MID;build1(lson); build1(rson);pushup1(x);}int query2(int l, int r, int x, int *s, int L, int R) {if(L<=l && r<=R) return s[x];int m=MID, ret=oo;if(L<=m) ret=min(ret, query2(lson, s, L, R));if(m<R) ret=min(ret, query2(rson, s, L, R));return ret;}int query1(int l, int r, int x, int L, int R, int LL, int RR) {if(L<=l && r<=R) return query2(1, mm, 1, mn[x], LL, RR);int m=MID, ret=oo;if(L<=m) ret=min(ret, query1(lson, L, R, LL ,RR));if(m<R) ret=min(ret, query1(rson, L, R, LL, RR));return ret;}ll ask(int x, int y) {int ret=query1(1, nn, 1, x, x+A-1, y, y+B-1); //printf("%d %d %d\n", x, y, ret);ll s=sum[x][y]-sum[x+A][y]-sum[x][y+B]+sum[x+A][y+B];return s-(ll)ret*(ll)A*(ll)B;}void dfs(int x, int y, int a, int b) {if(vis[x][y]) return;vis[x][y]=1;if(a<A) dfs(x+1, y, a+1, b);if(b<B) dfs(x, y+1, a, b+1);}void init() {CC(mn, 0x7f);read(nn); read(mm); read(A); read(B);for1(i, 1, nn) for1(j, 1, mm) read(a[i][j]);//for1(i, 1, nn) { for1(j, 1, mm) printf("%d\t", a[i][j]); puts(""); }for3(i, nn, 1) for3(j, mm, 1) sum[i][j]=sum[i+1][j]+sum[i][j+1]-sum[i+1][j+1]+a[i][j];build1(1, nn, 1);for1(i, 1, nn-A+1) for1(j, 1, mm-B+1) {home[++cnt].x=i;home[cnt].y=j;home[cnt].d=ask(i, j);}}int main() {init();sort(home+1, home+1+cnt, cmp);for1(i, 1, cnt) {int x=home[i].x, y=home[i].y;if(!vis[x][y] && !vis[x+A-1][y] && !vis[x][y+B-1] && !vis[x+A-1][y+B-1]) {ans[++ct]=home[i];dfs(x, y, 1, 1);}}printf("%d\n", ct);for1(i, 1, ct) printf("%d %d %lld\n", ans[i].x, ans[i].y, ans[i].d);return 0;}
Background
There are tens of millions of Chinese Characters in ande Guangxia.
Description
D finally became an architect. His first task was to build a house on a rectangle with N rows and M columns. The size of each house was a row and B columns (which cannot be rotated ).
Each cell in a rectangle has a height. If you select an area to build a house, you need to change the height of each cell in this area to the height of the smallest cell in this area, because this can make the land more flat. The cost of changing the height of a cell from H2 to H1 is the h2-h1, and the cost of a zone is the sum of the costs of each cell.
Now Mr. D builds a house in the following way:
1. First, find the area in which the House can be built at the minimum cost of the rectangular land (there cannot be a cell in this area that has already built a house). If there are multiple such areas, select the rows in the upper left corner as small as possible. If the rows are the same, select the columns as small as possible.
2. Build a house in this area.
3. Repeat the preceding operations until a house building area is not found.
Now you need to tell d How many houses he will build, the coordinates in the upper left corner of each house, and the cost of each house.
Format input format
The first line of the input includes four positive integers.
N, m, a, B (meaning as described above)
Next n rows, m non-negative integers in each row
Row I and column J indicate the height of the cell in row I and column J.
Output Format
Output the first act as a non-negative integer. "S" indicates the number of houses in total.
Next s line
Three integers I, j, V in each row: the row, column, and cost in the upper left corner of the second house.
Example 1 input 1 [copy]
3 2 1 22 51 23 5
Sample output 1 [copy]
32 1 13 1 21 1 3
Example 2 input 2 [copy]
5 5 2 29 9 4 4 10 10 3 3 9 3 3 6 3 8 1 4 2 10 9 8 7 10 10 3 5
Sample output 2 [copy]
42 2 34 4 131 4 144 1 15
Restrictions
2 S for each test point
Prompt
30% guarantee: n <= 10, m <= 10
70% guarantee: n <= 300, m <= 300
100% guarantee: n <= 1000, m <= 1000
1 <= A <= N, 1 <= B <= m, height of each cell <= 10 ^ 9
Source
Codeforces
[Vijos] 1750 build a house (line segment tree covers line segment tree + prefix and)