标签:read contain rect element integer positive rectangle line bottom
Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 524288/524288 K
Problem Description
Input
Output
Sample Input
Sample Output
题目大意就是一个坐标系有好多数值,有正有负,然后选定一个矩形区域,使得该区域内和最大,输出该和。
注意到最多只有2000个点,我们将坐标离散化后实际上就是一个矩形,然后找出和最大的子矩形。
这个问题有O(n3)的做法,就是枚举两行,然后将两行的每一列都压成一个数求一下最大的子区间和就好了。
但这里n最大为2000会TLE。
我们知道线段树是可以来维护区间的最大子区间和的,我们固定一行y1,枚举另一行y2从y1到ymax,每枚举一行我们将这一行的数xi加到线段树对应位置上,那我们可以O(1)知道答案。
但问题出在更新上,每枚举一行更新的复杂度岂不是要nlogn??
我们注意到如果离散后矩阵大小是2000*2000,而因为最多只有两千个点,那么每行只有一个数,我们其实对于每一行的更新只用更新一次,只要logn,如果这一行有多个数,那么行数也会相应的减少,而不会出现nlogn的情况
平均下来其实只要logn,总复杂度是n2logn。
最大和的子区间要不就是左儿子的子区间,要不就是右儿子的子区间,要不就是横跨左右儿子的子区间。
用线段树来维护区间的最大子区间和,维护四个量。
以该区间左端点为起始点向右延伸的最大子区间和ls
以该区间右端点为起始点向左延伸的最大子区间和rs
该区间的和s
该区间的最大子区间和ms
更新的话,s就左右儿子的s相加。
ls则是 左儿子的ls 与 左儿子的区间和s+右儿子的ls 中的最大值
rs则是 右儿子的rs 与 右儿子的区间和s+左儿子的rs 中的最大值
ms则是 左儿子的ms 与 右儿子的ms 与左儿子的rs+右儿子的ls 中的最大值
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <vector> 7 #include <cstdlib> 8 #include <cmath> 9 #include <string> 10 #define fo(i,a,b) for (int i=(a);i<=(b);++i) 11 #define fod(i,a,b) for (int i=(a);i>=(b);--i) 12 #define rep(i,a,b) for (int i=(a);i<(b);++i) 13 #define repd(i,a,b) for (int i=(a);i>(b);--i) 14 #define MAX(a,b) (((a)>(b)?(a):(b))) 15 #define N 2005 16 typedef long long LL; 17 using namespace std; 18 int n,m,t,x_rank[N],y_rank[N],x_size,y_size,x[N],y[N],xx,yy,biao[N][N],cnt[N]; 19 LL tu[N][N],w[N],ans; 20 bool sign[N][N]; 21 struct Segment_Tree{ 22 #define sth int root,int l,int r 23 #define lsth root<<1,l,mid 24 #define rsth root<<1|1,mid+1,r 25 #define lson root<<1 26 #define rson root<<1|1 27 LL lsum,rsum,asum,sum; 28 }seg[N*4]; 29 inline void readint(int &x){ 30 x=0; 31 char c; 32 int w=1; 33 for (c=getchar();c<‘0‘||c>‘9‘;c=getchar()) if (c==‘-‘) w=-1; 34 for(;c>=‘0‘&&c<=‘9‘;c=getchar()) x=(x<<3)+(x<<1)+(c^‘0‘); 35 x*=w; 36 } 37 inline void readlong(LL &x){ 38 x=0; 39 char c; 40 LL w=1; 41 for (c=getchar();c<‘0‘||c>‘9‘;c=getchar()) if (c==‘-‘) w=-1; 42 for(;c>=‘0‘&&c<=‘9‘;c=getchar()) x=(x<<3)+(x<<1)+(c^‘0‘); 43 x*=w; 44 } 45 void build(sth){ 46 if (l==r){ 47 seg[root].sum=seg[root].lsum=seg[root].rsum=seg[root].asum=0; 48 return; 49 } 50 int mid=(l+r)>>1; 51 build(lsth); 52 build(rsth); 53 seg[root].sum=seg[lson].sum+seg[rson].sum; 54 seg[root].lsum=MAX(seg[lson].lsum,seg[lson].sum+seg[rson].lsum); 55 seg[root].rsum=MAX(seg[rson].rsum,seg[rson].sum+seg[lson].rsum); 56 seg[root].asum=MAX(MAX(seg[lson].asum,seg[rson].asum),seg[lson].rsum+seg[rson].lsum); 57 } 58 void updata(sth,int xx,int pos){ 59 if (l==r){ 60 seg[root].sum+=tu[xx][r]; 61 seg[root].lsum+=tu[xx][r]; 62 seg[root].rsum+=tu[xx][r]; 63 seg[root].asum+=tu[xx][r]; 64 return; 65 } 66 int mid=(l+r)>>1; 67 if (pos<=mid) updata(lsth,xx,pos); 68 else updata(rsth,xx,pos); 69 seg[root].sum=seg[lson].sum+seg[rson].sum; 70 seg[root].lsum=MAX(seg[lson].lsum,seg[lson].sum+seg[rson].lsum); 71 seg[root].rsum=MAX(seg[rson].rsum,seg[rson].sum+seg[lson].rsum); 72 seg[root].asum=MAX(MAX(seg[lson].asum,seg[rson].asum),seg[lson].rsum+seg[rson].lsum); 73 } 74 void init(){ 75 ans=0; 76 fo(i,1,x_size) cnt[i]=0; 77 fo(i,1,x_size) fo(j,1,y_size) tu[i][j]=sign[i][j]=0; 78 x_size=y_size=0; 79 readint(n); 80 fo(i,1,n){ 81 readint(x[i]); 82 readint(y[i]); 83 readlong(w[i]); 84 x_rank[++x_size]=x[i]; 85 y_rank[++y_size]=y[i]; 86 } 87 sort(x_rank+1,x_rank+1+x_size); 88 sort(y_rank+1,y_rank+1+y_size); 89 x_size=unique(x_rank+1,x_rank+1+x_size)-(x_rank+1); 90 y_size=unique(y_rank+1,y_rank+1+y_size)-(y_rank+1); 91 fo(i,1,n) { 92 x[i]=lower_bound(x_rank+1,x_rank+1+x_size,x[i])-(x_rank); 93 y[i]=lower_bound(y_rank+1,y_rank+1+y_size,y[i])-(y_rank); 94 tu[x[i]][y[i]]+=w[i]; 95 if (!sign[x[i]][y[i]]){ 96 biao[x[i]][++cnt[x[i]]]=y[i]; 97 sign[x[i]][y[i]]=true; 98 } 99 } 100 } 101 int main(){ 102 readint(t); 103 n=x_size=y_size=0; 104 while (t--){ 105 init(); 106 fo(i,1,x_size){ 107 build(1,1,y_size); 108 fo(j,i,x_size){ 109 fo(k,1,cnt[j]) updata(1,1,y_size,j,biao[j][k]); 110 ans=MAX(ans,seg[1].asum); 111 } 112 } 113 printf("%lld\n",ans); 114 } 115 return 0; 116 }
2019 Multi-University Training Contest 6
标签:read contain rect element integer positive rectangle line bottom
原文地址:https://www.cnblogs.com/Lanly/p/11361242.html