Adding New Machine ZOJ
阿新 • • 發佈:2018-12-20
想到將舊機器向x或y方向擴充套件(m-1)個單位就好辦了 將查詢線段轉化為查詢單點 兩遍掃描線求矩形面積並就好了
一開始沒想到把問題轉化 用區間合併正面求的 一直WA 還沒調出來。。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+10; struct node0 { int x1,y1,x2,y2; }; struct node1 { int l,r; }; struct node2 { int l,r,h,f; }; struct node3 { int sum,val,leaf,f; }; node0 ret[maxn]; node1 pre[4*maxn]; node2 seg[2*maxn]; node3 tree[16*maxn]; int gou[2*maxn]; int w,h,n,tot,mm,len; bool cmpI(node1 n1,node1 n2) { return n1.l<n2.l; } bool cmpII(node2 n1,node2 n2) { return n1.h<n2.h; } void build(int l,int r,int cur) { int m; tree[cur].sum=pre[r].r-pre[l].l+1; tree[cur].val=0; tree[cur].leaf=0,tree[cur].f=0; if(l==r){ tree[cur].leaf=1; return; } m=(l+r)/2; build(l,m,2*cur); build(m+1,r,2*cur+1); } int getpos(int tp,int pos) { int l,r,m; if(!tp){ l=1,r=len; while(l<=r){ m=(l+r)/2; if(pre[m].l<pos) l=m+1; else if(pre[m].l==pos) return m; else r=m-1; } } else{ l=1,r=len; while(l<=r){ m=(l+r)/2; if(pre[m].r<pos) l=m+1; else if(pre[m].r==pos) return m; else r=m-1; } } } void pushup(int cur) { if(tree[cur].f>0) tree[cur].val=tree[cur].sum; else{ if(tree[cur].leaf) tree[cur].val=0; else tree[cur].val=tree[2*cur].val+tree[2*cur+1].val; } } void update(int pl,int pr,int f,int l,int r,int cur) { int m; if(pl<=l&&r<=pr) { tree[cur].f+=f; pushup(cur); return; } m=(l+r)/2; if(pl<=m) update(pl,pr,f,l,m,2*cur); if(pr>m) update(pl,pr,f,m+1,r,2*cur+1); pushup(cur); } ll solve() { ll res; int i,j,x1,y1,x2,y2; for(i=1;i<=n;i++){ x1=max(ret[i].x1-(mm-1),1),y1=ret[i].y1; x2=ret[i].x2,y2=ret[i].y2; seg[2*i-1].l=x1,seg[2*i-1].r=x2,seg[2*i-1].h=y1,seg[2*i-1].f=1; seg[2*i].l=x1,seg[2*i].r=x2,seg[2*i].h=y2+1,seg[2*i].f=-1; gou[2*i-1]=x1,gou[2*i]=x2; } tot=2*n; if(mm>1){ x1=max(w-(mm-2),1),y1=1; x2=w,y2=h; tot+=2; seg[tot-1].l=x1,seg[tot-1].r=x2,seg[tot-1].h=y1,seg[tot-1].f=1; seg[tot].l=x1,seg[tot].r=x2,seg[tot].h=y2+1,seg[tot].f=-1; gou[tot-1]=x1,gou[tot]=x2; } sort(seg+1,seg+tot+1,cmpII); len=tot; gou[++len]=1,gou[++len]=w; sort(gou+1,gou+len+1); len=unique(gou+1,gou+len+1)-gou-1; j=0; for(i=1;i<=len;i++){ j++; pre[j].l=gou[i],pre[j].r=gou[i]; } for(i=1;i+1<=len;i++){ if(gou[i]+1<=gou[i+1]-1){ j++; pre[j].l=gou[i]+1,pre[j].r=gou[i+1]-1; } } len=j; sort(pre+1,pre+len+1,cmpI); build(1,len,1); res=(ll)(w)*(ll)(h); for(i=1;i<=tot;i++){ res-=(ll)(seg[i].h-seg[i-1].h)*(ll)(tree[1].val); seg[i].l=getpos(0,seg[i].l),seg[i].r=getpos(1,seg[i].r); update(seg[i].l,seg[i].r,seg[i].f,1,len,1); } return res; } int main() { ll ans; int i; while(scanf("%d%d%d%d",&w,&h,&n,&mm)!=EOF){ for(i=1;i<=n;i++) scanf("%d%d%d%d",&ret[i].x1,&ret[i].y1,&ret[i].x2,&ret[i].y2); ans=solve(); if(mm>1){ swap(w,h); for(i=1;i<=n;i++) swap(ret[i].x1,ret[i].y1),swap(ret[i].x2,ret[i].y2); ans+=solve(); } printf("%lld\n",ans); } return 0; } /* 4 4 3 1 1 1 2 2 3 3 3 3 4 4 4 4 5 5 2 2 2 3 2 3 3 3 3 3 5 5 7 2 1 1 1 1 4 1 5 1 2 2 2 2 3 3 3 3 1 4 1 4 3 4 3 4 5 5 5 5 */