NC214894. Octasection
描述
输入描述
The first line contains a single integer ().
The -th line of the next lines contains integers (, , , ).
输出描述
If Wowo can cut the cake under the rules, the first line of the output should contain "YES" and the second line should contain integers , and (). If Wowo cannot cut the cake under the rules, output only one line containing "NO".
示例1
输入:
3 0 1 0 1 0 1 10 11 10 11 10 11 999999999 1000000000 999999999 1000000000 999999999 1000000000
输出:
YES 0 10 999999999
示例2
输入:
4 0 1 0 1 0 1 999999999 1000000000 0 1 0 1 0 1 999999999 1000000000 0 1 0 1 0 1 999999999 1000000000
输出:
YES 0 0 0
C++(clang++11) 解法, 执行用时: 544ms, 内存消耗: 104788K, 提交时间: 2021-01-24 11:23:35
#include<bits/stdc++.h> using namespace std; const int N=800005; struct sq{int x1,x2,y1,y2;}; struct node { int mn1,mx1,mn2,mx2,mx,t1,t2; node(){} }; int n,a[N][6],sx,sy,sz,st[N],tp; vector<int>v[3]; vector<sq>t[N]; node s[N],tr[N]; node operator+(node a,node b) { node c; c.mn1=min(a.mn1,b.mn1); c.mx1=max(a.mx1,b.mx1); c.mn2=min(a.mn2,b.mn2); c.mx2=max(a.mx2,b.mx2); c.mx=max(a.mx,b.mx); c.t1=c.t2=0; return c; } void build(int k,int l,int r) { tr[k].mn1=tr[k].mx1=0; tr[k].mn2=tr[k].mx2=tr[k].mx=sy+1; tr[k].t1=tr[k].t2=0; if(l==r) return; int mid=l+r>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); } void add(int k,int l,int r,int a,int b,sq x) { if(a>b) return; if(l==a&&r==b) { t[k].push_back(x); return; } int mid=l+r>>1; if(b<=mid) add(k<<1,l,mid,a,b,x); else if(a>mid) add(k<<1|1,mid+1,r,a,b,x); else add(k<<1,l,mid,a,mid,x),add(k<<1|1,mid+1,r,mid+1,b,x); } void rm(int k) { tp++; st[tp]=k; s[tp]=tr[k]; } void undo(int d) { while(tp!=d) { tr[st[tp]]=s[tp]; tp--; } } void upd1(int k,int v) { rm(k); tr[k].mn1=tr[k].mx1=tr[k].t1=v; tr[k].mx=tr[k].mx2-v; } void upd2(int k,int v) { rm(k); tr[k].mn2=tr[k].mx2=tr[k].t2=v; tr[k].mx=v-tr[k].mn1; } void pd(int k) { if(tr[k].t1==0&&tr[k].t2==0) return; rm(k); if(tr[k].t1) { upd1(k<<1,tr[k].t1); upd1(k<<1|1,tr[k].t1); tr[k].t1=0; } if(tr[k].t2) { upd2(k<<1,tr[k].t2); upd2(k<<1|1,tr[k].t2); tr[k].t2=0; } } void update1(int k,int l,int r,int a,int b,int v) { if(a>b) return; if(tr[k].mn1>=v) return; if(l==a&&r==b&&tr[k].mx1<=v) { upd1(k,v); return; } pd(k); int mid=l+r>>1; if(b<=mid) update1(k<<1,l,mid,a,b,v); else if(a>mid) update1(k<<1|1,mid+1,r,a,b,v); else update1(k<<1,l,mid,a,mid,v),update1(k<<1|1,mid+1,r,mid+1,b,v); rm(k); tr[k]=tr[k<<1]+tr[k<<1|1]; } void update2(int k,int l,int r,int a,int b,int v) { if(a>b) return; if(tr[k].mx2<=v) return; if(l==a&&r==b&&tr[k].mn2>=v) { upd2(k,v); return; } pd(k); int mid=l+r>>1; if(b<=mid) update2(k<<1,l,mid,a,b,v); else if(a>mid) update2(k<<1|1,mid+1,r,a,b,v); else update2(k<<1,l,mid,a,mid,v),update2(k<<1|1,mid+1,r,mid+1,b,v); rm(k); tr[k]=tr[k<<1]+tr[k<<1|1]; } void query(int k,int l,int r,int z) { if(l==r) { int x=l,y=tr[k].mn1; printf("YES\n%d %d %d\n",v[0][x-1],v[1][max(y-1,0)],v[2][z-1]); exit(0); } pd(k); int mid=l+r>>1; if(tr[k<<1].mx>=0) query(k<<1,l,mid,z); else query(k<<1|1,mid+1,r,z); } void sol(int k,int l,int r) { int d=tp; for(auto i:t[k]) { update1(1,1,sx,1,i.x1-1,i.y1); update1(1,1,sx,i.x2+1,sx,i.y1); update2(1,1,sx,1,i.x1-1,i.y2); update2(1,1,sx,i.x2+1,sx,i.y2); } if(l==r) { if(tr[1].mx>=0) query(1,1,sx,l); undo(d); return; } int mid=l+r>>1; sol(k<<1,l,mid); sol(k<<1|1,mid+1,r); undo(d); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=0;j<6;j++) { scanf("%d",&a[i][j]); v[j/2].push_back(a[i][j]+(j&1)); } } for(int j=0;j<3;j++) { sort(v[j].begin(),v[j].end()); v[j].erase(unique(v[j].begin(),v[j].end()),v[j].end()); } sx=v[0].size()-1,sy=v[1].size()-1,sz=v[2].size()-1; for(int i=1;i<=n;i++) { for(int j=0;j<6;j++) { a[i][j]=lower_bound(v[j/2].begin(),v[j/2].end(),a[i][j]+(j&1))-v[j/2].begin()+1; if(j&1) a[i][j]--; } add(1,1,sz,1,a[i][4]-1,{a[i][0],a[i][1],a[i][2],a[i][3]}); add(1,1,sz,a[i][5]+1,sz,{a[i][0],a[i][1],a[i][2],a[i][3]}); } build(1,1,sx); sol(1,1,sz); puts("NO"); return 0; }