CF-1252H-Twin Buildings(扫描线+线段树)

题目链接:https://codeforces.com/contest/1252/problem/H

题目大意:给出n个矩形小岛,每个小岛有两个属性:长和宽。我们要建两座相同的房子,要求房子的面积最大。这里相同的房子意思是边长对应相等。问最大的面积是多少。可以将一个岛分成两半一边一个。

思路:将所有岛都放倒(长的边贴在x轴上)。然后找最大的重叠面积,即覆盖面积>=2的。最后和最大的单独岛比较一下就好了 。

注意有一个坑点,输出,如果直接输出%lf的话,可能会输出1.499999999999的情况,所以特判一下整数输出?学到了。。。

ACCode:

#include
#include
#include
#include
#include
// srand((unsigned)time(NULL));rand();
      
#include//unordered_map
#include//multiset
#include
#include
#include
#include
#include
#include
#include
#include
 
#define ll long long
#define PII pair
#define PLL pair
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
      
const int MAXN=1e5+10;
//const int MAXM=10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)

struct SegTree{
	struct Tree{
		int l,r,flag;
		ll rl,rr;
		ll len1,len2;
	};
	Tree T[MAXN<<2];
	
	void PushUp(int rt){
		if(T[rt].flag) T[rt].len1=T[rt].rr-T[rt].rl;
		else if(T[rt].l+1==T[rt].r) T[rt].len1=0;
		else T[rt].len1=T[rt<<1].len1+T[rt<<1|1].len1;
		
		if(T[rt].flag>1) T[rt].len2=T[rt].rr-T[rt].rl;
		else if(T[rt].l+1==T[rt].r) T[rt].len2=0;
		else if(T[rt].flag==1) T[rt].len2=T[rt<<1].len1+T[rt<<1|1].len1;
		else T[rt].len2=T[rt<<1].len2+T[rt<<1|1].len2; 
	}
	void Build(ll l,ll r,int rt,ll A[]){
		T[rt].l=l;T[rt].r=r;T[rt].flag=0;
		T[rt].rl=A[l];T[rt].rr=A[r];
		T[rt].len1=T[rt].len2=0;
		if(l+1==r) return ;
		int mid=(l+r)>>1;
		Build(l,mid,rt<<1,A);Build(mid,r,rt<<1|1,A);
		PushUp(rt);
	}
	void Update(ll ql,ll qr,int val,int rt){
		if(ql<=T[rt].rl&&T[rt].rr<=qr){
			T[rt].flag+=val;PushUp(rt);
			return ;
		}
		if(qr<=T[rt<<1].rr) Update(ql,qr,val,rt<<1);
		else if(ql>=T[rt<<1|1].rl) Update(ql,qr,val,rt<<1|1);
		else{
			Update(ql,qr,val,rt<<1);
			Update(ql,qr,val,rt<<1|1);
		}PushUp(rt);
	}
	void Show(int rt){
		printf("l=%d r=%d rl=%d rr=%d len1=%d len2=%d flag=%d\n",T[rt].l,T[rt].r,T[rt].rl,T[rt].rr,T[rt].len1,T[rt].len2,T[rt].flag);
		if(T[rt].l==T[rt].r) return ;
		Show(rt<<1);Show(rt<<1|1);
	}
};
struct Line{
	ll x,y1,y2,flag;
	friend int operator < (Line a,Line b){
		return a.x

 

你可能感兴趣的:(线段树)