Submission #81764

#TimeUsernameProblemLanguageResultExecution timeMemory
81764AngelKnowsSwap (BOI16_swap)C++14
100 / 100
164 ms55448 KiB
#include <bits/stdc++.h> using namespace std; #define FOR(i,n) for (int i=1;i<=n;i++) #define REP(i,a,b) for (int i=a;i<=b;i++) #define pb push_back #define fi first #define se second #define pi pair<int,int> #define mp make_pair #define sz(x) ((int)(x).size()) typedef long long ll; const int inf=0x3f3f3f3f; const ll linf=1e18; const int N=200000+10; const double eps=1e-5; const int mo=1e9+7; int n; int a[N],b[N]; int p=1; int q[N][46],len[N]; // q[i]存放在i处的预约元素的原来位置 int mn,pos; bool used[N],vis[N]; struct edge { int to,nxt; } e[2*N]; int tot; int head[N]; int cnt; int dn[N]; int last[N]; int fa[N]; int o[N]; // o[i]=1表示第i点取了,o[i]=2表示第i点确定不取,o[i]=0表示不确定 int dir(int x,int y) { // 判断y是x的左后代还是右后代 // 要先保证y是x的后代 if (last[2*x]<dn[y]) { return 1; // 右后代 } else return 0; // 左后代 } void insert(int x,int y) { e[++tot].to=y,e[tot].nxt=head[x],head[x]=tot; e[++tot].to=x,e[tot].nxt=head[y],head[y]=tot; } void dfs(int x) { dn[x]=++cnt; int y; for (int i=head[x];i;i=e[i].nxt) { y=e[i].to; if (y!=fa[x]) { fa[y]=x; dfs(y); } } last[x]=cnt; } bool ok(int s,int t) { if (s==t) { if (o[s]!=1&&(2*s>n||o[2*s]!=1)&&(2*s+1>n||o[2*s+1]!=1)) { return 1; } else return 0; } if (s>t) { if (s%2==0) { if (o[s]!=2&&(s+1>n||o[s+1]!=1)) return 1; else return 0; } else { if (o[s]!=2) return 1; else return 0; } } bool f=0; if (last[s]<dn[t]) { if (o[s]==2) return 0; s++; if (s==t) { if (o[t]!=2&&(2*t>n||o[2*t]!=1)&&(2*t+1>n||o[2*t+1]!=1)) return 1; else return 0; } else { if (o[s]==2) return 0; if (!dir(s,t)) s*=2; else s=2*s+1; } } else { if (o[s]==1) return 0; if (!dir(s,t)) s*=2; else s=2*s+1; } for (;;) { if (o[s]==2) return 0; if (s%2) if (o[s-1]==1) return 0; if (s==t) break; if (!dir(s,t)) s*=2; else s=2*s+1; } if ((2*t<=n&&o[2*t]==1)||(2*t+1<=n&&o[2*t+1]==1)) return 0; return 1; } void walk(int s,int t) { if (s==t) { o[s]=2; if (2*s<=n) o[2*s]=2; if (2*s+1<=n) o[2*s+1]=2; return; } if (s>t) { if (s%2==0) { o[s]=1; if (s+1<=n) o[s+1]=2; } else { o[s]=1; } return; } if (last[s]<dn[t]) { o[s]=1; s++; if (s==t) { o[t]=1; if (2*t<=n) o[2*t]=2; if (2*t+1<=n) o[2*t+1]=2; return; } else { o[s]=1; if (!dir(s,t)) s*=2; else s=2*s+1; } } else { o[s]=2; if (!dir(s,t)) s*=2; else s=2*s+1; } for (;;) { o[s]=1; if (s%2) o[s-1]=2; if (s==t) break; if (!dir(s,t)) s*=2; else s=2*s+1; } if (2*t<=n) o[2*t]=2; if (2*t+1<=n) o[2*t+1]=2; } int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d",&n); FOR(i,n) scanf("%d",&a[i]); FOR(i,n) { if (2*i+1<=n) insert(i,2*i+1); if (2*i<=n) insert(i,2*i); } dfs(1); q[1][++len[1]]=1; REP(i,2,n) { //cout<<i<<endl; q[i][++len[i]]=i; q[i/2][++len[i/2]]=i; if (i==2*p+1) { mn=inf,pos=0; FOR(j,len[p]) if (!used[a[q[p][j]]]&&a[q[p][j]]<mn) { //cout<<q[p][j]<<" "<<p<<endl; if (ok(q[p][j],p)) { mn=a[q[p][j]]; pos=q[p][j]; } } walk(pos,p); b[p]=a[pos]; used[b[p]]=1; int pp; FOR(j,len[p]) { pp=q[p][j]; if (pos!=pp&&!used[a[pp]]&&!vis[a[pp]]) { vis[a[pp]]=1; if (pp!=2*p+1) q[i-1][++len[i-1]]=pp; q[i][++len[i]]=pp; } } FOR(j,len[p]) vis[a[q[p][j]]]=0; ++p; } } while (p<=n) { mn=inf,pos=0; FOR(j,len[p]) if (!used[a[q[p][j]]]&&a[q[p][j]]<mn) { //cout<<q[p][j]<<" "<<p<<endl; if (ok(q[p][j],p)) { mn=a[q[p][j]]; pos=q[p][j]; } } //FOR(i,n) cout<<o[i]<<" "; walk(pos,p); b[p]=a[pos]; used[b[p]]=1; int pp; FOR(j,len[p]) { pp=q[p][j]; if (pos!=pp&&!used[a[pp]]&&!vis[a[pp]]) { vis[a[pp]]=1; if (pp!=2*p+1) if (2*p<=n) q[2*p][++len[2*p]]=pp; } } FOR(j,len[p]) vis[a[q[p][j]]]=0; ++p; } //FOR(i,n) cout<<o[i]<<endl; FOR(i,n) printf("%d ",b[i]); printf("\n"); return 0; }

Compilation message (stderr)

swap.cpp: In function 'bool ok(int, int)':
swap.cpp:83:7: warning: unused variable 'f' [-Wunused-variable]
  bool f=0;
       ^
swap.cpp: In function 'int main()':
swap.cpp:162:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d",&n);
     ~~~~~^~~~~~~~~
swap.cpp:163:19: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     FOR(i,n) scanf("%d",&a[i]);
              ~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...