HDU 4419 다채로운 사각형 (선분 트 리)
5953 단어 HDU
제목: 평면 상의 사각형 을 보 여 줍 니 다. 이 사각형 의 색깔 은 세 가지 R, G, B 가 있 습 니 다.교차 하 는 영역 은 각각 RG, RB, GB, RGB.출력 색상 은 R, G, B, RG, RB, GB, RGB 의 면적 은 각각 얼마 입 니까?
사고방식: 경 기 를 할 때 표준적 인 사각형 면적 에 비해 다양한 색깔 의 면 을 출력 해 야 한다 고 생각한다.그 당시 에 온라인 트 리 의 노드 에서 만 모든 색 채 를 기록 하고 다른 사람의 용 척 원 리 를 보고 알 수 있 었 다. 원래 이렇게 할 수 있 었 다. 위 에 7 가지 색 채 를 설치 한 면적 은 각각 1, 2, 3, 4, 5, 6, 7 이 었 다.
a = 1 + 2 + 3 + 4 + 5 + 6 + 7 (모든 사각형 을 1 회 면적 으로 구 합 니 다)
b = 1 + 2 + 4 + 5 + 6 + 7 (R 과 G 의 사각형 을 한 번 구하 기)
c = 2 + 3 + 4 = 5 + 6 + 7 (G 와 B 의 사각형 을 한 번 구하 기)
d = 1 + 3 + 4 + 5 + 6 + 7 (R 과 B 의 사각형 을 한 번 구하 기)
e = 1 + 4 + 5 + 7 (R 의 사각형 을 한 번 구하 기)
f = 2 + 4 + 6 + 7 (G 의 사각형 을 한 번 구하 기)
g = 3 + 5 + 6 + 7 (B 의 사각형 을 한 번 구하 기)
위의 7 개 식 에서 얻 을 수 있 습 니 다:
1=a-c;2=a-d;3=a-b;6=a-2-3-e;5=a-1-3-f;4=a-1-2-g;7=a-1-2-3-4-5-6;
문제 가 척척 풀리다.
struct NODE
{
char color[5];
__int64 x1,y1,x2,y2;
};
struct Node
{
__int64 L,R;
__int64 Len; // ,
__int64 cover; //
};
struct node
{
__int64 x,y1,y2;
bool bLeft;
node(){}
node(__int64 _x,__int64 _y1,__int64 _y2,bool _bLeft)
{
x=_x;
y1=_y1;
y2=_y2;
bLeft=_bLeft;
}
};
const int MAX=10005;
NODE p[MAX];
node L[MAX*2];
Node a[MAX*10];
__int64 y[MAX*2];
int n;
bool cmp(node a,node b)
{
return a.x<b.x;
}
inline int DB(__int64 x)
{
if(x==0) return 0;
return x>0?1:-1;
}
int find(__int64 y[],int n,__int64 val)
{
int low=0,high=n-1,mid;
while(low<=high)
{
mid=(low+high)>>1;
if(DB(val-y[mid])==0) return mid;
if(DB(val-y[mid])==1) low=mid+1;
else high=mid-1;
}
if(DB(val-y[0])==0) return 0;
return n-1;
}
void insert(int t,int L,int R)
{
if(a[t].L==L&&a[t].R==R)
{
a[t].Len=y[R+1]-y[L];
a[t].cover++;
return;
}
int mid=(a[t].L+a[t].R)>>1;
if(R<=mid) insert(t*2,L,R);
else if(L>mid) insert(t*2+1,L,R);
else
{
insert(t*2,L,mid);
insert(t*2+1,mid+1,R);
}
if(a[t].cover==0) a[t].Len=a[t*2].Len+a[t*2+1].Len;
}
void del(int t,int L,int R)
{
if(a[t].L==L&&a[t].R==R)
{
a[t].cover--;
if(a[t].cover==0)
{
if(a[t].L==a[t].R) a[t].Len=0;
else a[t].Len=a[t*2].Len+a[t*2+1].Len;
}
return;
}
int mid=(a[t].L+a[t].R)>>1;
if(R<=mid) del(t*2,L,R);
else if(L>mid) del(t*2+1,L,R);
else
{
del(t*2,L,mid);
del(t*2+1,mid+1,R);
}
if(a[t].cover==0) a[t].Len=a[t*2].Len+a[t*2+1].Len;
}
void build(int t,int L,int R)
{
a[t].L=L;
a[t].R=R;
a[t].cover=0;
a[t].Len=0;
if(L==R) return;
int mid=(L+R)>>1;
build(t*2,L,mid);
build(t*2+1,mid+1,R);
}
__int64 cal_cross_area(NODE p[],int n)
{
if(!n) return 0;
int i,k;
__int64 x1,y1,x2,y2;
for(i=0;i<n;i++)
{
x1=p[i].x1;
y1=p[i].y1;
x2=p[i].x2;
y2=p[i].y2;
y[i*2]=y1;
y[i*2+1]=y2;
L[i*2]=node(x1,y1,y2,true);
L[i*2+1]=node(x2,y1,y2,false);
}
sort(y,y+2*n);
sort(L,L+2*n,cmp);
k=unique(y,y+2*n)-y;
build(1,0,k-2);
__int64 ans=0;
for(i=0;i<2*n-1;i++)
{
int left=find(y,k,L[i].y1) ;
int right=find(y,k,L[i].y2) ;
if(L[i].bLeft) insert(1,left,right-1);
else del(1,left,right-1);
ans+=((__int64)a[1].Len)*(L[i+1].x-L[i].x);
}
return ans;
}
int C,num=0;
int main()
{
for(scanf("%d",&C);C--;)
{
scanf("%d",&n);
int i;
__int64 x1,y1,x2,y2;
for(i=0;i<n;i++)
{
scanf("%s%I64d%I64d%I64d%I64d",p[i].color,&x1,&y1,&x2,&y2);
p[i].x1=x1;
p[i].y1=y1;
p[i].x2=x2;
p[i].y2=y2;
}
__int64 a,b,c,d,e,f,g;
a=cal_cross_area(p,n);
NODE Q[MAX];
int N;
N=0;
for(i=0;i<n;i++) if(p[i].color[0]=='R'||p[i].color[0]=='G')
Q[N++]=p[i];
b=cal_cross_area(Q,N);
N=0;
for(i=0;i<n;i++) if(p[i].color[0]=='B'||p[i].color[0]=='G')
Q[N++]=p[i];
c=cal_cross_area(Q,N);
N=0;
for(i=0;i<n;i++) if(p[i].color[0]=='R'||p[i].color[0]=='B')
Q[N++]=p[i];
d=cal_cross_area(Q,N);
N=0;
for(i=0;i<n;i++) if(p[i].color[0]=='R')
Q[N++]=p[i];
e=cal_cross_area(Q,N);
N=0;
for(i=0;i<n;i++) if(p[i].color[0]=='G')
Q[N++]=p[i];
f=cal_cross_area(Q,N);
N=0;
for(i=0;i<n;i++) if(p[i].color[0]=='B')
Q[N++]=p[i];
g=cal_cross_area(Q,N);
__int64 _1,_2,_3,_4,_5,_6,_7;
_1=a-c;
_2=a-d;
_3=a-b;
_6=a-_2-_3-e;
_5=a-_1-_3-f;
_4=a-_1-_2-g;
_7=a-_1-_2-_3-_4-_5-_6;
printf("Case %d:
",++num);
printf("%I64d
%I64d
%I64d
%I64d
%I64d
%I64d
%I64d
",_1,_2,_3,_4,_5,_6,_7);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[HDU] 4089 활성화 확률 DPdp[i][j]를 모두 i개인의 대기열인 Tomato가 j위 서버가 마비될 확률로 역추를 사용하면 우리는 상태 이동 방정식을 얻을 수 있다. i == 1 : dp[1][1] = dp[1][1] * p1 + dp[1]...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.