# Codeforces Round #656 (Div. 3)

## A. Three Pairwise Maximums

### 题解

#include<iostream>
#include<cstdio>
using namespace std;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int main()
{
int T=read();
while(T--)
{
int x=read(),y=read(),z=read();
if(x!=y&&y!=z&&z!=x){puts("NO");continue;}
if(x==y&&x>=z){printf("YES\n%d %d %d\n",x,1,z);continue;}
if(x==z&&x>=y){printf("YES\n%d %d %d\n",1,x,y);continue;}
if(y==z&&y>=x){printf("YES\n%d %d %d\n",x,1,z);continue;}
puts("NO");
}
}


## B. Restore the Permutation by Merger

### 题解

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
#define MAX 111
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int T,n,a[MAX];
bool vis[MAX];
int main()
{
T=read();
while(T--)
{
n=read();
for(int i=1;i<=n+n;++i)a[i]=read();
memset(vis,0,sizeof(vis));
for(int i=1;i<=n+n;++i)if(!vis[a[i]])printf("%d ",a[i]),vis[a[i]]=true;
printf("\n");
}
return 0;
}


## C. Make It Good

### 题解

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 200200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,a[MAX];
int main()
{
int T=read();
while(T--)
{
n=read();
for(int i=1;i<=n;++i)a[i]=read();
a[n+1]=-1;
int p=n;while(p>1&&a[p-1]>=a[p])--p;
while(p>1&&a[p-1]<=a[p])--p;
printf("%d\n",p-1);
}
return 0;
}


## D. a-Good String

### 题解

$i$层的状态数是$2^i$（只有这么多可选择的位置）

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
#define MAX 200200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,sz[22],len[22];
char c[MAX];
vector<int> f[22];
int main()
{
int T=read();
while(T--)
{
n=read();scanf("%s",c+1);
if(n==1)
{
if(c[1]=='a')puts("0");
else puts("1");
continue;
}
int p=0;while((1<<p)<n)++p;
for(int i=0;i<p;++i)f[i].resize(sz[i]=(1<<(i+1))),len[i]=n>>(i+1);
f[p].resize(n);len[p]=len[p-1];sz[p]=sz[p-1];
for(int i=0;i<=p;++i)
for(int j=1,t=0;j<=n;j+=len[i],++t)
{
for(int k=j;k<j+len[i];++k)if(c[k]!=('a'+i))++f[i][t];
if(i!=0)
{
if(i!=p)f[i][t]+=f[i-1][(t>>1)^1];
else f[i][t]+=f[i-1][t^1];
}
}
int ans=n;
for(int i=0;i<n;++i)ans=min(ans,f[p][i]);
printf("%d\n",ans);
for(int i=0;i<=p;++i)f[i].clear();
}
}


## E. Directing Edges

### 题解

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
#define MAX 200200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,m;
vector<int> E[MAX];
int dg[MAX],p[MAX],rk[MAX];
int U[MAX],V[MAX],O[MAX];
queue<int> Q;
bool Topsort()
{
for(int i=1;i<=n;++i)
for(int j=0,l=E[i].size();j<l;++j)
dg[E[i][j]]++;
for(int i=1;i<=n;++i)if(!dg[i])Q.push(i);
int cnt=0;
while(!Q.empty())
{
int u=Q.front();Q.pop();
p[++cnt]=u;
for(int j=0,l=E[u].size();j<l;++j)
if(!--dg[E[u][j]])Q.push(E[u][j]);
}
return cnt==n;
}
int main()
{
int T=read();
while(T--)
{
n=read();m=read();int cnt=0;
for(int i=1;i<=m;++i)
{
int o=read(),u=read(),v=read();
if(o)E[u].push_back(v);
++cnt,U[cnt]=u,V[cnt]=v;O[cnt]=o;
}
if(Topsort())
{
puts("YES");
for(int i=1;i<=n;++i)rk[p[i]]=i;
for(int i=1;i<=cnt;++i)
if(rk[U[i]]>rk[V[i]])swap(U[i],V[i]);
for(int i=1;i<=cnt;++i)printf("%d %d\n",U[i],V[i]);
}
else puts("NO");
for(int i=1;i<=n;++i)E[i].clear(),dg[i]=0;
}
return 0;
}



## F. Removing Leaves

### 题解

$set$维护相邻节点是一个很好的方法（也更加符合复杂度），因为你需要实时的删除掉相邻节点。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#define ll long long
using namespace std;
#define MAX 200200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int ls[MAX];
set<int> E[MAX];
void Add(int u,int v){E[u].insert(v);}
int n,K;
queue<int> Q;
int main()
{
int T=read();
while(T--)
{
n=read();K=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
for(int i=1;i<=n;++i)if(E[i].size()==1)Q.push(i);
while(!Q.empty())
{
int v=Q.front();Q.pop();
int u=*E[v].begin();
++ls[u];E[u].erase(v);
if(E[u].size()==1&&ls[u]%K==0)Q.push(u);
}
int ans=0;
for(int i=1;i<=n;++i)ans+=ls[i]/K,ls[i]=0,E[i].clear();
printf("%d\n",ans);
}
return 0;
}


## G. Columns Swaps

### 题解

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
#define MAX 400400
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,a[3][MAX],cnt[MAX];
struct P{int x,y;}p[MAX][3];
int f[MAX],val[MAX],cho[MAX];
int getf(int x){return (f[x]==x)?x:(f[x]=getf(f[x]));}
void Link(int x,int y){if(getf(x)==getf(y))return;val[getf(y)]+=val[getf(x)];f[getf(x)]=getf(y);}
int main()
{
int T=read();
while(T--)
{
n=read();bool fl=true;
for(int i=1;i<=2;++i)
for(int j=1;j<=n;++j)a[i][j]=read();
for(int i=1;i<=2;++i)
for(int j=1;j<=n;++j)if(a[i][j]<1||a[i][j]>n)fl=false;
if(!fl){puts("-1");continue;}
for(int i=1;i<=n;++i)cnt[i]=0;
for(int i=1;i<=2;++i)
for(int j=1;j<=n;++j)p[a[i][j]][++cnt[a[i][j]]]=(P){i,j};
for(int i=1;i<=n;++i)if(cnt[i]!=2)fl=false;
int ans=0;
for(int i=1;i<=n+n;++i)f[i]=i,val[i]=(i<=n);
for(int i=1;i<=n;++i)
if(p[i][1].x==p[i][2].x)Link(p[i][1].y,p[i][2].y+n),Link(p[i][1].y+n,p[i][2].y);
else Link(p[i][1].y,p[i][2].y),Link(p[i][1].y+n,p[i][2].y+n);
for(int i=1;i<=n;++i)if(getf(i)==getf(i+n))fl=false;
if(!fl){puts("-1");continue;}
for(int i=1;i<=n+n;++i)cho[i]=0;
for(int i=1;i<=n;++i)
if(getf(i)==i)
{
if(val[getf(i)]<val[getf(i+n)])cho[getf(i)]=1;
else cho[getf(i+n)]=1;
ans+=min(val[getf(i)],val[getf(i+n)]);
}
printf("%d\n",ans);
for(int i=1;i<=n;++i)if(cho[getf(i)])printf("%d ",i);
if(ans)puts("");
}
return 0;
}


posted @ 2020-08-02 23:16  小蒟蒻yyb  阅读(866)  评论(6编辑  收藏  举报