COCI 2008-2009 Final

Description:

在一个二维平面内,有 n n n个矩形的毯子,初始,在格子坐标 ( 0 , 0 ) (0,0) (0,0)处,有一桶油,过时间 t t t后,它会向四周扩散(8个方向),即为一个中心在 ( 0 , 0 ) (0,0) (0,0)的边长为 2 t 2t 2t的正方形。现在有 q q q个询问,对于每个询问求 t i t_i ti时油覆盖的毯子的面积。注意:毯子之间的重叠部分被覆盖也算。
n ≤ 1 0 5 , x , y ≤ 1 0 6 n\le10^5,x,y\le 10^6 n105,x,y106

Solution:

  • 这道题大概是一道几何数学题吧…
  • 首先不断画图分析(瞎猜),发现随着 t t t的增长,覆盖毯子的面积是一个数列,其数列先是一个等差数列,再是一个常数列。
  • 为了方便差分,我们可以将二维平面的每个象限都翻转到第一象限,也是因为油是正方形才可以这样。
  • 这样复杂度为 Θ ( n + m ) \Theta(n+m) Θ(n+m)

Code:

#include
using namespace std;
#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
#define SREP(i,f,t) for(int i=(f),i##_end_=(t);i=i##_end_;--i)
#define ll long long
templateinline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templateinline bool chkmax(T &x,T y){return xinline void Rd(T &x){
	x=0;char c;int f=1;
	while((c=getchar())<48)if(c=='-')f=-1;
	do x=(x<<1)+(x<<3)+(c^48);
	while((c=getchar())>47);
	x*=f;
}
const int N=1e5+2,M=1e6;

int n,m;
struct point{
	int x1,y1,x2,y2;
}A[N];

struct p50{
	void solve(){
		while(m--){
			int t;Rd(t);
			int X1=-t,Y1=-t,X2=t,Y2=t;
			int x1,y1,x2,y2;
			ll ans=0;
			REP(i,1,n) {
				x1=max(A[i].x1,X1);
				y1=max(A[i].y1,Y1);
				x2=min(A[i].x2,X2);
				y2=min(A[i].y2,Y2);
				
				if(x1<=x2 && y1<=y2) ans+=1ll*(x2-x1+1)*(y2-y1+1);
			}

			printf("%lld\n",ans);			
		}
	}
}p1;

struct p100{

	struct f{
		ll b,k;
	};
	vectorF[M+5];
	
	ll ans[M+5];
	
	
	void Line(int x,int y,int top){
		if(x

你可能感兴趣的:(COCI)