YMD的課件是真的毒,YYB的也很毒。spa
LOJdebug
我是一個一個Subtask作的。。。code
\(O(n^2)\)枚舉每兩個點有沒有邊便可。遞歸
鏈的狀況的話,咱們能夠維護一條鏈\([l,r]\),這個區間和編號不要緊,只是表示\(l,r\)是端點。get
考慮每次加一個點進來,咱們首先能夠判一下是\(x...l...r\)仍是\(l...r...x\)。string
而後判斷\(x\)和端點有沒有直接的連邊,若是有,連上,返回。it
不然,二分出路徑上最小的點的編號\(t\),而後兩端遞歸作下去。io
樹,以\(0\)爲根深度\(log\)。class
直接把每一個點的兒子找出來,而後把子樹內的點一一分配便可。bug
樹,無特殊性質。
和鏈差很少,可是要把整個集合和連進來的點判斷。
有點細節。
圖,無特殊性質。
和樹也差很少,只是每次發現當前點相鄰的時候要二分出每條與集合相連的邊。
因爲點度\(\le 7\)因此複雜度是對的。
這題花了我\(3h\),果真仍是我太菜了。
細節就看\(code\)吧。
\(code\)
#include "park.h" #define pb push_back #include<queue> #include<vector> #include<cstring> #include<algorithm> #include<cstdio> const int N=1400; static int A[1400],o[1400]; int n; inline void debug(){for(int i=0;i<n;++i)printf("%d ",A[i]);puts("");} inline bool ask(int l,int r,int *A){if(l>r)std::swap(l,r);return Ask(l,r,A);} inline void answer(int l,int r){if(l>r)std::swap(l,r);Answer(l,r);} namespace w1 { void work() { for(int i=0;i<n;++i) { A[i]=1; for(int j=i+1;j<n;A[j]=0,++j) if(A[j]=1,ask(i,j,A))answer(i,j); A[i]=0; } } } namespace w2 { int binary(int p,int q); int link(int l,int r); int link(int &l,int &r,int x); void work(); } namespace w3 { std::vector<int>G[N],son[N]; void solve(int u); void work(); } namespace w4 { std::vector<int>nS,G[N],tS; int pos[N],vis[N],ov[N]; inline void pre(int x){if(x)A[x]=1;else for(int x:nS)A[x]=1;} inline void del(int x){if(x)A[x]=0;else for(int x:nS)A[x]=0;} inline void add(int l,int r){G[l].pb(r),G[r].pb(l),answer(l,r);} inline void Link(int l,int r); int binary(int p,int q); void link(int l,int r); void work(); } namespace w5 { std::vector<int>nS,G[N],tS,pos; int vis[N],ov[N],now; inline void pre(int x){if(x)A[x]=1;else for(int x:nS)A[x]=1;} inline void del(int x){if(x)A[x]=0;else for(int x:nS)A[x]=0;} inline void add(int l,int r){G[l].pb(r),G[r].pb(l),answer(l,r);} int binary(int p,int q); void work(); void bfs(int fr,std::vector<int>&pos); void calc(std::vector<int>&pos,int r); inline void Link(int r); void link(int l,int r); } void Detect(int T, int _n) { n=_n;memset(A,0,n<<2),memset(o,0,n<<2); if(T==1)return w1::work(); if(T==2)return w2::work(); if(T==3)return w3::work(); if(T==4)return w4::work(); if(T==5)return w5::work(); } namespace w2 { int binary(int p,int q) { int l=1,r=n-1,ans=r;A[p]=A[q]=1; while(l<=r) { int mid=l+r>>1; for(int i=0;i<=mid ;++i)if(i!=p&&i!=q&&!o[i])A[i]=0; for(int i=mid+1;i<n;++i)if(i!=p&&i!=q&&!o[i])A[i]=1; if(ask(p,q,A))l=mid+1; else r=mid-1,ans=mid; } return ans; } int link(int l,int r) { for(int i=0;i<n;++i)A[i]=(i==l||i==r); if(ask(l,r,A))return answer(l,r),o[l]=o[r]=1; int x=binary(l,r);return link(l,x)+link(x,r); } int link(int &l,int &r,int x) { int to,tot=0; if(l==r)to=l; else { for(int i=0;i<n;++i)A[i]=i!=r; if(ask(x,l,A))to=l;else to=r; } if(to==r)return r=x,link(to,x); return l=x,link(x,to); } void work() { int l=0,r=0,cnt=o[0]=1; while(cnt<n) { for(int i=1;i<n;++i) if(!o[i])cnt+=link(l,r,i); } } } namespace w3 { void solve(int u) { A[u]=1; for(int x:G[u]) if(A[x]=1,ask(x,u,A)) answer(u,x),son[u].pb(x),A[x]=0,o[x]=1; else A[x]=0; for(int i=0;i<n;++i)A[i]=1; for(int x:G[u]) if(!o[x]) for(int y:son[u]) { A[y]=0; if(!ask(x,u,A)){G[y].pb(x);A[y]=1;break;} A[y]=1; } memset(A,0,n<<2); for(int x:son[u])solve(x); } void work() { for(int i=1;i<n;++i)G[0].pb(i); o[0]=1,solve(0); } } namespace w4 { inline void Link(int l,int r) { tS.pb(r);o[r]=1;if(l)return add(l,r); if(A[0]=1,A[r]=1,ask(0,r,A))return A[0]=0,A[r]=0,add(0,r); std::queue<int>Q;Q.push(0);memset(vis,0,sizeof vis); int cnt=-1;vis[0]=1; while(!Q.empty()) { int u=pos[++cnt]=Q.front();Q.pop(); for(int x:G[u])if(ov[x]&&!vis[x])Q.push(x),vis[x]=1; } int L=1,R=cnt,ans=L; while(L<=R) { int mid=L+R>>1; for(int i=1;i<=mid;++i)A[pos[i]]=1; if(ask(0,r,A))R=mid-1,ans=mid; else L=mid+1; for(int i=1;i<=mid;++i)A[pos[i]]=0; } add(pos[ans],r),A[0]=A[r]=0; } int binary(int p,int q) { pre(p),pre(q); int l=1,r=n-1,ans=r; while(l<=r) { int mid=l+r>>1; for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=1; if(ask(p,q,A))l=mid+1;else r=mid-1,ans=mid; for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=0; } del(p),del(q); return ans; } void link(int l,int r) { pre(l),pre(r); if(ask(l,r,A))return del(l),del(r),Link(l,r); del(l),del(r);int x=binary(l,r); link(l,x),link(x,r); } void work() { o[0]=ov[0]=1;nS.pb(0); for(int i=1;i<n;++i) if(!o[i]) { tS.clear(),link(0,i),nS.insert(nS.end(),tS.begin(),tS.end()); for(int x:tS)ov[x]=1; } } } namespace w5 { int binary(int p,int q) { pre(p),pre(q); int l=1,r=n-1,ans=r; while(l<=r) { int mid=l+r>>1; for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=1; if(ask(p,q,A))l=mid+1;else r=mid-1,ans=mid; for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=0; } del(p),del(q); return ans; } void bfs(int fr,std::vector<int>&pos) { std::queue<int>Q;Q.push(fr);ov[fr]=0; while(!Q.empty()) { int u=Q.front();Q.pop(),pos.pb(u); for(int x:G[u])if(ov[x])ov[x]=0,Q.push(x); } } void calc(std::vector<int>&pos,int r) { for(int x:pos)A[x]=1;A[r]=1; if(!ask(pos[0],r,A)){for(int x:pos)A[x]=0;A[r]=0;pos.clear();return;} for(int i=1;i<pos.size();++i)A[pos[i]]=0; int L=1,R=pos.size()-1,ans=-1;A[r]=A[pos[0]]=1; std::vector<int>fz,ff; if(ask(pos[0],r,A))ans=0; else while(L<=R) { int mid=L+R>>1; for(int i=1;i<=mid;++i)A[pos[i]]=1; for(int i=mid+1;i<pos.size();++i)A[pos[i]]=0; if(!ask(pos[0],r,A))L=mid+1;else R=mid-1,ans=mid; for(int i=1;i<=mid;++i)A[pos[i]]=0; } A[pos[0]]=A[r]=0;if(ans==-1)return pos.clear(); tS.pb(pos[ans]),add(pos[ans],r); for(std::vector<int>::iterator it=nS.begin();it!=nS.end();++it) if(*it==pos[ans]){nS.erase(it);break;} for(std::vector<int>::iterator it=pos.begin();it!=pos.end();++it) if(*it==pos[ans]){pos.erase(it);break;} for(int x:pos)ov[x]=1; while(pos.size()) { bfs(pos[0],fz);ff=fz;std::sort(ff.begin(),ff.end()); for(std::vector<int>::iterator it=pos.begin();it!=pos.end();) if(*(std::lower_bound(ff.begin(),ff.end(),*it))==*it) it=pos.erase(it); else ++it; calc(fz,r); } } inline void Link(int r) { std::queue<int>Q;Q.push(0);memset(vis,0,sizeof vis); int cnt=-1;vis[0]=1;pos.resize(nS.size()),ov[0]=0; while(!Q.empty()) { int u=pos[++cnt]=Q.front();Q.pop(); for(int x:G[u])if(!vis[x])Q.push(x),vis[x]=1; } calc(pos,r); } void link(int l,int r) { pre(l),pre(r); if(ask(l,r,A)) { del(l),del(r),tS.pb(r);o[r]=1;Link(r); nS.insert(nS.end(),tS.begin(),tS.end()); tS.clear();return; } del(l),del(r);int x=binary(l,r); link(l,x),link(x,r); } void work() { o[0]=ov[0]=1;nS.pb(0); for(int i=1;i<n;++i) if(!o[i])link(0,i); } }