一个问题
查看原帖
一个问题
374064
GOOBA楼主2020/8/22 13:05

蒟蒻初学扫描线, 一开始没想到后来看了题解自己写,写完发现只有80分,后来与题解疯狂对比,找不到实质上的不同(我感觉),然后来看贴,发现要把tot改成2 * n , 但是题解却写的是tot诶,为什么? 以下是题解代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define mid ((l+r)>>1)
using namespace std;

const int maxn=1e4+10;
int n,tot,w,h;
int yy[maxn<<1];					//离散化的y轴 
int rm[maxn<<3],flag[maxn<<3];		//rm表示区间最大值,flag为懒标记 八倍数组,因为2n条线段,线段树要4倍。 
struct seg
{
    int x,y1,y2,c;
    seg(){}
    seg(int xx,int yy1,int yy2,int cc){x=xx,y1=yy1,y2=yy2,c=cc;}
}line[maxn<<1];

bool cmp(const seg &a,const seg &b)//这里注意排序,x相同时先处理入边 
{
	if(a.x==b.x)return a.c>b.c;
    return a.x<b.x;
}
void pushdown(int t,int l,int r)//下传懒标记 
{
    if(flag[t]==0)return;
    rm[t]+=flag[t];
    if(l!=r)		//这里主要防止越界 
    {
        flag[t<<1]+=flag[t];
        flag[t<<1|1]+=flag[t];
    }
    flag[t]=0;
}
void modify(int t,int l,int r,int x,int y,int z)//区间修改 
{
    if(x<=l&&r<=y)
    {
        flag[t]+=z;
        return;
    }
    if(x<=mid)modify(t<<1,l,mid,x,y,z);
    if(y>mid)modify(t<<1|1,mid+1,r,x,y,z);
    pushdown(t<<1,l,mid);
    pushdown(t<<1|1,mid+1,r);
    rm[t]=max(rm[t<<1],rm[t<<1|1]);	//回传最值 
}
int main()
{
    int t=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d %d",&n,&w,&h);
        memset(rm,0,sizeof(rm));
        memset(flag,0,sizeof(flag));
        for(int i=1;i<=n;i++)
        {
            int x=0,y=0,c=0;
            scanf("%d %d %d",&x,&y,&c);
            line[i]=seg(x,y,y+h-1,c);
            line[i+n]=seg(x+w-1,y,y+h-1,-c);
            yy[i]=y+h-1;
            yy[i+n]=y;
        }
        n<<=1;//处理的是2n条线段 
        sort(yy+1,yy+1+n);//排序 
        tot=unique(yy+1,yy+1+n)-yy-1;//去重 
        sort(line+1,line+1+n,cmp);//根据横坐标排序 
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            int l=lower_bound(yy+1,yy+1+tot,line[i].y1)-yy;//二分离散化 
            int r=lower_bound(yy+1,yy+1+tot,line[i].y2)-yy;
           modify(1,1,tot,l,r,line[i].c);        ans=max(ans,rm[1]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

我的代码

#include<bits/stdc++.h>
using namespace std ;
#define int long long
#define kkksc signed main
#define ddd double
#define maxn 1000010
#define lc o << 1
#define rc ((o << 1) | 1 )
#define mem(x) memset(x , 0 , sizeof(x))
//#define mid ((l + r) >> 1)
int read(){
	int ans = 0 , f = 1 ; char ch = getchar() ;
	while(ch < '0' || ch > '9'){ if(ch == '-') f = -1 ; ch = getchar() ; }
	while(ch >= '0' && ch <= '9') {
		ans = (ans * 10) + ch - '0' ;
		ch = getchar() ;
	}
	return ans * f ;
}
int n , w , h ; 
struct scanline{
	int l , r, h , val;
	bool operator <(const scanline &x) const {return h == x.h ? val > x.val : h < x.h ;}
}line[maxn];
int maxx[maxn << 3] , tag[maxn << 3] ; 
int yy[maxn << 3] ; 
inline void pushup(int o){
	maxx[o] = max(maxx[lc] , maxx[rc]) ; 
	return  ;
}
inline void pushdown(int o){
	maxx[lc] += tag[o] ; maxx[rc] += tag[o] ; 
	tag[lc] += tag[o] ; tag[rc] += tag[o] ; 
	tag[o] = 0 ; 
	return ; 
}
inline void change(int o , int l , int r , int ql , int qr , int k){
//	printf("l : %lld r : %lld ql : %lld qr : %lld \n", l , r , ql ,qr) ; 
	if(ql > r || qr < l) return ; 
	if(ql <= l && r <= qr){
//		printf("will change : l : %lld r : %lld ql : %lld qr : %lld \n", l , r , ql ,qr) ; 
		maxx[o] += k ; 
		tag[o] += k ; 
		return ; 
	}
	int mid = (l + r) >> 1 ; 
	if(tag[o]) pushdown(o);
	change(lc , l , mid , ql , qr , k) ; 
	change(rc , mid + 1 , r , ql ,qr , k) ; 
	pushup(o) ;
	return ; 
}
int t ; 
void clear(){
	mem(maxx) , mem(tag) ; 
} 
kkksc(){
//	freopen("test.in" , "r" , stdin) ;
//	freopen("test.out" , "w"  , stdout) ;
	t = read() ; 
	while(t--){
		n = read() , w = read() - 1 , h = read() - 1; 
		for(int i = 1 ; i <= n ; i++){
			int x = read() , y = read() , l = read() ; 
			line[i * 2 - 1] = (scanline){y , y + h , x , l} ; 
			line[i * 2] = (scanline){y , y + h , x + w , -l} ; 
			yy[i * 2 - 1] = y ; 
			yy[i * 2] = y + h ; 
		}
		n *= 2 ; 
		sort(yy + 1 , yy + 1 + n) ;
		sort(line + 1 , line + 1 + n) ; 
		int ans = 0 ; 
		int tot = unique(yy + 1 , yy + 1 + n) - yy - 1 ; 
		for(int i = 1 ; i <= n ; i++){
			int l = lower_bound(yy+1,yy+1+n , line[i].l  ) - yy; 
			int r = lower_bound(yy+1,yy+1+n , line[i].r ) - yy ;
			change(1 , 1 , tot , l , r , line[i].val ); 
			ans = max(ans , maxx[1]) ; 
		}
		cout << ans << endl ; 
		clear() ; 
	}
}

问题出在这里

题解的代码:
modify(1,1,tot,l,r,line[i].c);//修改,这里注意是l和r,一开始我写的r-1竟然对了9个(但实际上是错误的) 
我的代码:
change(1 , 1 , tot , l , r , line[i].val ); 
把tot改成n就过了。。。。
2020/8/22 13:05
加载中...