一开始没什么想法,看了点提示,居然是把每个点换成矩形。代码立即敲出来了,不过由于二分查找的时候形参没用LL,结果就悲剧了一天。幸好把代码打出来找到错误了,做完又去看了个离线算法。。。
ACcode:
在线:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int nsize=111111;
LL X[nsize<<1];
int sum[nsize<<3],cov[nsize<<3];
struct Line
{
LL lx,rx,y;
int f;
Line(){}
Line(LL a,LL b,LL c,int d) : lx(a),rx(b),y(c),f(d){}
bool operator < (const Line &cmp) const {
if(y==cmp.y)
return f>cmp.f;
return y<cmp.y;
}
}line[nsize<<1];
int Max(int a1,int a2)
{
return a1>a2?a1:a2;
}
int Fin(LL key,int k)
{
int l=0,r=k;
while (l<=r)
{
int m=(l+r)>>1;
if (X[m]==key) return m;
else if (X[m]>key) r=m-1;
else l=m+1;
}
return -1;
}
void PushUp(int rt)
{
sum[rt]=Max(sum[rt<<1],sum[rt<<1|1]);
}
void PushDown(int rt)
{
if (cov[rt]!=0)
{
cov[rt<<1]+=cov[rt];
sum[rt<<1]+=cov[rt];
cov[rt<<1|1]+=cov[rt];
sum[rt<<1|1]+=cov[rt];
cov[rt]=0;
}
}
void update(int rt,int l,int r,int L,int R,int v)
{
if (L<=l&&r<=R)
{
cov[rt]+=v;
sum[rt]+=v;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if (L<=m) update(rt<<1,l,m,L,R,v);
if (R>m) update(rt<<1|1,m+1,r,L,R,v);
PushUp(rt);
}
int main()
{
LL x,y;
int n,i,w,h,c,nx,ny,ans;
while (~scanf("%d %d %d",&n,&w,&h))
{
for (i=0;i<n;i++)
{
scanf("%I64d %I64d %d",&x,&y,&c);
X[i]=x; X[n+i]=x+w-1;
line[i]=Line(x,x+w-1,y,c);
line[n+i]=Line(x,x+w-1,y+h-1,-c);
}
sort(X,X+n*2);
sort(line,line+n*2);
for (nx=0,i=1;i<n*2;i++)
if (X[i]!=X[i-1]) X[++nx]=X[i];
memset(sum,0,sizeof(sum));
memset(cov,0,sizeof(cov));
for (ans=i=0;i<n*2;i++)
{
int L=Fin(line[i].lx,nx);
int R=Fin(line[i].rx,nx);
if (L<=R) update(1,0,nx,L,R,line[i].f);
ans=Max(ans,sum[1]);
}
printf("%d\n",ans);
}
return 0;
}
离线:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
using namespace std;
const int mm=10001;
const int mn=mm<<2;
struct star
{
int x,y,c;
bool operator < (const star &cmp) const {
return x<cmp.x;
}
}g[mm];
int dly[mn],sum[mn];
int y[mm],m;
int Max(int a1,int a2)
{
return a1>a2?a1:a2;
}
void pushdown(int rt)
{
sum[ls]+=dly[rt];
sum[rs]+=dly[rt];
dly[ls]+=dly[rt];
dly[rs]+=dly[rt];
dly[rt]=0;
}
void pushup(int rt)
{
sum[rt]=Max(sum[ls],sum[rs]);
}
void updata(int L,long long R,int val,int l,int r,int rt)
{
if(L<=y[l]&&R>=y[r])
{
sum[rt]+=val;
dly[rt]+=val;
return;
}
if(dly[rt])pushdown(rt);
int m=(l+r)>>1;
if(L<=y[m])updata(L,R,val,lson);
if(R>=y[m+1])updata(L,R,val,rson);
pushup(rt);
}
int main()
{
int i,j,k,n,w,h,ans;
while(~scanf("%d%d%d",&n,&w,&h))
{
for(i=0;i<n;++i)
{
scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].c);
y[i]=g[i].y;
}
sort(y,y+n);
sort(g,g+n);
for(m=i=0;i<n;++i)
if(y[m]!=y[i])y[++m]=y[i];
memset(dly,0,sizeof(dly));
memset(sum,0,sizeof(sum));
for(ans=j=i=0;i<n;++i)
{
updata(g[i].y,(long long)g[i].y+h-1,g[i].c,0,m,1);
while(j<=i&&g[i].x-g[j].x+1>w)
{
updata(g[j].y,(long long)g[j].y+h-1,-g[j].c,0,m,1);
++j;
}
ans=Max(ans,sum[1]);
}
printf("%d\n",ans);
}
return 0;
}