我用上一道题的方法把这个题A掉了。。。
记得这题是做之前寒假后学树状数组碰到的,但是没做。
前天比赛也想到这题了,没往深处想,以为不一样呢(因为当时很坚定我的想法呐。。。)
赛后看了这个题,基本是一样了,比赛那题两个点可以重复,而且边缘的点也算,这个的话不是。
依旧老做法,把每个点作为矩形的中心,建立两条边界线。因为边界重合不算,那么如果x相同的话,负的那条线应该排前面。然后插入删除线段神马的。计算线段最大覆盖次数即可。亮度用线段的权值表示。
依旧更新到底了。可以不更新到底的,记录当前加的数和当前区间的max即可。
250ms,不怎么快。
想想用树状数组应该怎么做呢。(貌似不能用树状数组)。
————————————————————————————————————————————————————————
悲剧啊,看网上代码,貌似想法和我的一样哎。。难道这就是这题的标准解?? = =。。。
只不过好多都是以星星为左下角做的,其实是一样的。
不过是以左下角了,可以避免用double ,不过得用long long了。
下面代码是以左下角的。这种转化的思想很强大呢。
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=s; i<t; i++)
#define BUG puts("here!!!")
#define STOP system("pause")
using namespace std;
const int MAX = 20010;
struct point {int x,y; long long lx, ly, rx, ry; int val;};
point p[MAX/2];
long long x[MAX], y[MAX];
int ans;
struct Sline{int x,y1,y2;int flag;};
Sline l[MAX];
void add_line(int x1, int y1, int x2, int y2,int &cnt,int flag)
{
l[cnt].x = x1; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt++].flag = flag;
l[cnt].x = x2; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt++].flag = -flag;
}
bool cmp(Sline a,Sline b)
{
if( a.x == b.x ) return a.flag < b.flag;
return a.x < b.x;
}
struct Tnode{ // 一维线段树
int l,r,val,max;
int len() { return r - l;}
int mid() { return MID(l,r);}
bool in(int ll,int rr) { return l >= ll && r <= rr; }
void lr(int ll,int rr){ l = ll; r = rr;}
};
Tnode node[MAX<<2];
void Build(int t,int l,int r)
{
node[t].val = node[t].max = 0;
node[t].lr(l,r);
if( node[t].len() == 1 ) return ;
int mid = MID(l,r);
Build(L(t),l,mid);
Build(R(t),mid,r);
}
void Updata(int t,int l,int r,int val)
{
if( node[t].in(l,r) )
{
node[t].val += val;
node[t].max += val;
ans = max(node[t].max, ans);
return ;
}
if( node[t].len() == 1 ) return ;
node[L(t)].val += node[t].val;
node[L(t)].max += node[t].val;
node[R(t)].val += node[t].val;
node[R(t)].max += node[t].val;
node[t].val = 0;
int mid = node[t].mid();
if( l >= mid )
Updata(R(t),l,r,val);
else
if( r <= mid )
Updata(L(t),l,r,val);
else
{
Updata(L(t),l,r,val);
Updata(R(t),l,r,val);
}
node[t].max = max(node[L(t)].max, node[R(t)].max);
ans = max(node[t].max, ans);
}
int solve(int cx, int cy, int n)
{
sort(x, x+cx);
sort(y, y+cy);
cx = unique(x, x+cx) - x;
cy = unique(y, y+cy) - y;
int cnt = 0;
FOR(i, 0, n)
{
int x2 = lower_bound(x, x+cx, p[i].rx) - x;
int y2 = lower_bound(y, y+cy, p[i].ry) - y;
int x1 = lower_bound(x, x+cx, p[i].lx) - x;
int y1 = lower_bound(y, y+cy, p[i].ly) - y;
add_line(x1, y1, x2, y2, cnt, p[i].val);
}
sort(l, l+cnt, cmp);
Build(1, 0, cy+1);
FOR(i, 0, cnt)
Updata(1, l[i].y1, l[i].y2, l[i].flag);
return ans;
}
int main()
{
int l;
int n, w;
while( scanf("%d%d%d", &n, &w, &l) != EOF )
{
int cntx = 0, cnty = 0;
ans = 0;
FOR(i, 0, n)
{
scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].val);
p[i].lx = p[i].x; p[i].ly = p[i].y;
p[i].rx = p[i].x*1ll + w; p[i].ry = p[i].y*1ll + l;
x[cntx++] = p[i].lx;
x[cntx++] = p[i].rx;
y[cnty++] = p[i].ly;
y[cnty++] = p[i].ry;
}
solve( cntx, cnty, n);
printf("%d\n",ans);
}
return 0;
}