[Vijos] 1750 build a house (line segment tree covers line segment tree + prefix and)

Source: Internet
Author: User

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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.