Codeforces Round #567 (Div. 2) E2 A Story of One Country (Hard)
https://codeforces.com/contest/1181/problem/E2
想到了划分的方法跟题解一样,但是没理清楚复杂度,很难受。
看了题解觉得很有道理,还是自己太菜了。
然后直接开始写,四个if写的太难受了180+行。
ac之后看了红名大佬的代码,简直woc,好短,四个sort我分开写了,但是红名大佬写的很巧妙,借鉴了一下代码长度缩短到110行左右,红名大佬np,特此记录。
使用静态链表,复杂度计算 T(n) = T(a1)+T(a2)+T(a3) ... + O(nlogn) ( ai<=n/2)
傻逼版
#include<bits/stdc++.h> #include<ext/rope> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #define mst(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) #define lson (rt<<1) #define rson (rt<<1|1) using namespace __gnu_pbds; using namespace __gnu_cxx; using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; typedef pair<ull,ull> pull; typedef pair<int,int> pii; const int mod = 1e9+7; ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;return res; } const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f; const int maxn = 2e5+50; void co(){ cout<<"NO";exit(0); } int x1[maxn],x2[maxn],y1[maxn],y2[maxn]; bool cmp0(const int&le,const int&ri){ return x1[le]<x1[ri]; } bool cmp1(const int&le,const int&ri){ return y1[le]<y1[ri]; } bool cmp2(const int&le,const int&ri){ return x2[le]>x2[ri]; } bool cmp3(const int&le,const int&ri){ return y2[le]>y2[ri]; } int pre[4][maxn],nx[4][maxn]; void store(int *f){ for(int i=0;i<4;++i) f[i]=nx[i][0]; } void read(int *f){ for(int i=0;i<4;++i) nx[i][0]=f[i]; } void init(vector<int>&use){ sort(use.begin(),use.end(),cmp0); int p=0; for(int v:use){ nx[0][p]=v; pre[0][v]=p; p=v; } nx[0][p]=0; sort(use.begin(),use.end(),cmp1); p=0; for(int v:use){ nx[1][p]=v; pre[1][v]=p; p=v; } nx[1][p]=0; sort(use.begin(),use.end(),cmp2); p=0; for(int v:use){ nx[2][p]=v; pre[2][v]=p; p=v; } nx[2][p]=0; sort(use.begin(),use.end(),cmp3); p=0; for(int v:use){ nx[3][p]=v; pre[3][v]=p; p=v; } nx[3][p]=0; } void del(int p){ for(int i=0;i<4;++i){ int a=pre[i][p],b=nx[i][p]; nx[i][a]=b;pre[i][b]=a; } } void solve(vector<int>&use){ if(use.size()<=1)return; init(use); // for(int i=0;i<4;++i){ // int p=nx[i][0]; // while(p!=0){ // cout<<p<<" "; // p=nx[i][p]; // } // cout<<endl; // } // exit(0); int sz=use.size(); while(sz>1){ int now[4]; store(now); int v[4]={x2[now[0]],y2[now[1]],x1[now[2]],y1[now[3]]}; bool ok=false; for(int i=1;i<sz;++i){ for(int d=0;d<4;++d) now[d]=nx[d][now[d]]; if(x1[now[0]]>=v[0]){ vector<int>son; for(int j=nx[0][0];j!=now[0];j=nx[0][j]) son.push_back(j); for(int v:son) del(v); store(now); solve(son); sz-=i; read(now); ok=true; break; }else v[0]=max(v[0],x2[now[0]]); if(y1[now[1]]>=v[1]){ vector<int>son; for(int j=nx[1][0];j!=now[1];j=nx[1][j]) son.push_back(j); for(int v:son) del(v); store(now); solve(son); sz-=i; read(now); ok=true; break; }else v[1]=max(v[1],y2[now[1]]); if(x2[now[2]]<=v[2]){ vector<int>son; for(int j=nx[2][0];j!=now[2];j=nx[2][j]) son.push_back(j); for(int v:son) del(v); store(now); solve(son); sz-=i; read(now); ok=true; break; }else v[2]=min(v[2],x1[now[2]]); if(y2[now[3]]<=v[3]){ vector<int>son; for(int j=nx[3][0];j!=now[3];j=nx[3][j]) son.push_back(j); for(int v:son) del(v); store(now); solve(son); sz-=i; read(now); ok=true; break; }else v[3]=min(v[3],y1[now[3]]); } if(!ok)co(); } } vector<int>a; int main() { #ifdef local freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin>>n; for(int i=1;i<=n;++i) cin>>x1[i]>>y1[i]>>x2[i]>>y2[i]; for(int i=1;i<=n;++i) a.push_back(i); solve(a); cout<<"YES"; return 0; }
借鉴大佬代码改良版
#include<bits/stdc++.h> #include<ext/rope> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #define mst(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) #define lson (rt<<1) #define rson (rt<<1|1) using namespace __gnu_pbds; using namespace __gnu_cxx; using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; typedef pair<ull,ull> pull; typedef pair<int,int> pii; const int mod = 1e9+7; ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;return res; } const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f; const int maxn = 2e5+50; void co(){ cout<<"NO";exit(0); } pii a[4][maxn]; int pre[4][maxn],nx[4][maxn]; void store(int *f){ for(int i=0;i<4;++i) f[i]=nx[i][0]; } void read(int *f){ for(int i=0;i<4;++i) nx[i][0]=f[i]; } void init(vector<int>&use){ for(int i=0;i<4;++i){ sort(use.begin(),use.end(),[&](const int &le,const int&ri){ return a[i][le]<a[i][ri]; }); int p=0; for(int v:use){ nx[i][p]=v; pre[i][v]=p; p=v; } nx[i][p]=0; } } void del(int p){ for(int i=0;i<4;++i){ int a=pre[i][p],b=nx[i][p]; nx[i][a]=b;pre[i][b]=a; } } void solve(vector<int>&use){ if(use.size()<=1)return; init(use); int sz=use.size(); while(sz>1){ int now[4],v[4]; store(now); for(int i=0;i<4;++i) v[i]=a[i][now[i]].second; bool ok=false; for(int i=1;i<sz and !ok;++i){ for(int d=0;d<4 and !ok;++d){ now[d]=nx[d][now[d]]; if(a[d][now[d]].first>=v[d]){ vector<int>son; for(int j=nx[d][0];j!=now[d];j=nx[d][j]) son.push_back(j); for(int v:son) del(v); store(now); solve(son); sz-=i; read(now); ok=true; }else v[d]=max(v[d],a[d][now[d]].second); } } if(!ok)co(); } } vector<int>uu; int main() { #ifdef local freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin>>n; for(int i=1;i<=n;++i){ int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2; a[0][i]=pii(x1,x2); a[1][i]=pii(y1,y2); a[2][i]=pii(-x2,-x1); a[3][i]=pii(-y2,-y1); } for(int i=1;i<=n;++i) uu.push_back(i); solve(uu); cout<<"YES"; return 0; }