题解:
感觉这题和别人的做法不一样。。。呵呵呵。。。调了一百年。。
设家坐标为(a,b),对于每个点(x,y),可以转化为|a-x|+|b-y|<=k
对于每个点,它的影响范围是一个菱形(也就是一个正方形啦。。),也就是一个图上有若干个正方形。
然后我就把这个坐标轴选择了45度。
好难画不画了,正交分解一下就可以了。
然后题目就转化成正方形各种交里的最大值。
正方形有x和y两个元素,但是很明显我们只能维护一个。。
所以我以x轴建立线段树,对于每个正方形按照y从小到大排序。
维护一个指针j,表示当前前j个正方形已经和现在在处理的第i个正方形没有交集。每次都要先把j更新(看看它是否能后移)。
然后我们在当前正方形的两端a[i].x~a[i].y这一段+a[i].d
每个点维护当前的和d以及该区间的最大值mx。每次做完之后,用t[1].mx更新答案。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<ctime> 6 #include<queue> 7 #include<algorithm> 8 using namespace std; 9 10 const int N=1001000,INF=(int)1e9; 11 int n,K,L,tl,ans; 12 struct trnode{ 13 int l,r,lc,rc,d,mx,lazy; 14 }t[4*N]; 15 struct node{ 16 int x,y,d; 17 }a[N]; 18 19 bool cmp(node x,node y){return x.y<y.y;} 20 int maxx(int x,int y){return x>y ? x:y;} 21 int minn(int x,int y){return x<y ? x:y;} 22 23 int read() 24 { 25 int x=0,f=1; char ch=getchar(); 26 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();} 27 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} 28 return x*f; 29 } 30 31 int bt(int l,int r) 32 { 33 int x=++tl; 34 t[x].l=l;t[x].r=r; 35 t[x].lc=t[x].rc=0; 36 t[x].mx=0;t[x].d=0; 37 t[x].lazy=0; 38 if(l<r) 39 { 40 int mid=(l+r)/2; 41 t[x].lc=bt(l,mid); 42 t[x].rc=bt(mid+1,r); 43 } 44 return x; 45 } 46 47 void pd(int x) 48 { 49 if(t[x].lazy==0) return ; 50 int d=t[x].lazy,lc=t[x].lc,rc=t[x].rc; 51 t[x].lazy=0; 52 t[x].d+=d; 53 t[x].mx+=d; 54 if(lc) t[lc].lazy+=d; 55 if(rc) t[rc].lazy+=d; 56 } 57 58 void change(int x,int l,int r,int d) 59 { 60 pd(x); 61 if(t[x].l==l && t[x].r==r) 62 { 63 t[x].lazy+=d; 64 pd(x); 65 return ; 66 } 67 int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2; 68 if(r<=mid) change(lc,l,r,d); 69 else if(l>mid) change(rc,l,r,d); 70 else 71 { 72 change(lc,l,mid,d); 73 change(rc,mid+1,r,d); 74 } 75 pd(x);pd(lc);pd(rc); 76 t[x].mx=maxx(t[lc].mx,t[rc].mx); 77 } 78 79 int main() 80 { 81 // freopen("a.in","r",stdin); 82 // freopen("me.out","w",stdout); 83 freopen("lazy.in","r",stdin); 84 freopen("lazy.out","w",stdout); 85 n=read();K=read(); 86 // scanf("%d%d",&n,&K); 87 int x,y,tx,ty,nx=INF,ny=INF,mx=0;tl=0;L=2*K; 88 for(int i=1;i<=n;i++) 89 { 90 a[i].d=read();x=read();y=read(); 91 // scanf("%d%d%d",&a[i].d,&x,&y); 92 tx=x,ty=y+K; 93 a[i].x=tx-ty; 94 a[i].y=tx+ty; 95 96 nx=minn(nx,a[i].x); 97 ny=minn(ny,a[i].y); 98 } 99 for(int i=1;i<=n;i++) 100 { 101 a[i].x-=nx-1; 102 a[i].y-=ny-1; 103 mx=maxx(mx,a[i].x); 104 } 105 mx+=10;ans=0; 106 sort(a+1,a+1+n,cmp); 107 bt(1,mx); 108 int j=1; 109 change(1,a[1].x,minn(mx,a[1].x+L),a[1].d); 110 ans=maxx(ans,t[1].mx); 111 for(int i=2;i<=n;i++) 112 { 113 while(j<i && a[i].y-L>a[j].y) 114 { 115 change(1,a[j].x,minn(mx,a[j].x+L),-a[j].d); 116 ans=maxx(ans,t[1].mx); 117 j++; 118 } 119 change(1,a[i].x,minn(mx,a[i].x+L),a[i].d); 120 ans=maxx(ans,t[1].mx); 121 } 122 printf("%d\n",ans); 123 return 0; 124 }
时间: 2024-10-21 03:35:33