# Codeforces Global Round 16部分题解

### A.Median Maximization

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<time.h>
#include<set>
using namespace std;
#define rg register
#define ll long long
#define ull unsigned long long
#define lowbit(i) i&(-i)
#define pb(x) push_back(x)
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
const int maxn=1e5+10,mod=1e9+7;
int T,n,s;
int main(){
while(T--){
printf("%d\n",s/(n-(n+1)/2+1));
}
}


### B.MIN-MEX Cut

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<time.h>
#include<set>
using namespace std;
#define rg register
#define ll long long
#define ull unsigned long long
#define lowbit(i) i&(-i)
#define pb(x) push_back(x)
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
const int maxn=1e5+10,mod=1e9+7;
int T,n,m;char a[maxn];
int main(){
while(T--){
scanf("%s",a+1);n=strlen(a+1);m=0;
for(rg int i=1;i<=n;i++)if(a[i]!=a[i-1]&&a[i]=='0')m++;
if(m>=2)m=2;printf("%d\n",m);
}
}


### C.MAX-MEX Cut

1、同为$$1$$，那么$$\rm MEX\begin{bmatrix}1\\1 \end{bmatrix}=0$$

2、同为$$0$$，那么$$\rm MEX\begin{bmatrix}0\\0 \end{bmatrix}=1$$

3、不相同，那么$$\rm MEX\begin{bmatrix}0\\1 \end{bmatrix}=2,\rm MEX\begin{bmatrix}1\\0 \end{bmatrix}=2$$

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<time.h>
#include<set>
using namespace std;
#define rg register
#define ll long long
#define ull unsigned long long
#define lowbit(i) i&(-i)
#define pb(x) push_back(x)
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
const int maxn=1e5+10,mod=1e9+7;
int T,n,m,b[maxn],vis[maxn];char a[2][maxn];
int main(){
while(T--){
scanf("%s",a[0]+1);m=0;scanf("%s",a[1]+1);
for(rg int i=1;i<=n;i++){
if(a[0][i]=='1'&&a[1][i]=='1')b[i]=1;
if(a[0][i]=='0'&&a[1][i]=='0')b[i]=2;
if(a[0][i]=='0'&&a[1][i]=='1')b[i]=0;
if(a[0][i]=='1'&&a[1][i]=='0')b[i]=0;
}
for(rg int i=1;i<=n;i++){
if(b[i]==0)m+=2;
if(b[i]==2)m+=1;
if(b[i]==1){
if(b[i-1]==2&&!vis[i-1])m++;
else if(b[i+1]==2)vis[i+1]=1,m++;
}
}
for(rg int i=1;i<=n;i++)vis[i]=b[i]=0;
printf("%d\n",m);
}
}


### D.Seating Arrangements (hard version)

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<time.h>
#include<set>
using namespace std;
#define rg register
#define ll long long
#define ull unsigned long long
#define lowbit(i) i&(-i)
#define pb(x) push_back(x)
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
const int maxn=310,mod=1e9+7;
int T,n,m,ans,a[maxn*maxn],f[maxn][maxn],b[maxn*maxn];
struct oo{int x,y;}l[maxn*maxn],r[maxn*maxn],d[maxn*maxn];
map<int,int>mp;
int main(){
while(T--){
memset(f,0,sizeof f);
memset(l,0,sizeof l);
memset(r,0,sizeof r);
memset(d,0,sizeof d);
memset(b,0,sizeof b);
memset(a,0,sizeof a);
mp.clear();
sort(b+1,b+n*m+1);int g=0,s=1;
for(rg int i=1;i<=n*m;i++)if(!mp[b[i]])mp[b[i]]=++g;
for(rg int i=1;i<=n*m;i++)
if(b[i]!=b[i+1]){
l[mp[b[i]]]=(oo){(s-1)/m+1,(s-1)%m+1};
r[mp[b[i]]]=(oo){(i-1)/m+1,(i-1)%m+1};
if(r[mp[b[i]]].x>l[mp[b[i]]].x)d[mp[b[i]]]=(oo){l[mp[b[i]]].x,m};
else d[mp[b[i]]]=r[mp[b[i]]];
s=i+1;
}
for(rg int i=1;i<=n*m;i++){
int xx=d[mp[a[i]]].x,yy=d[mp[a[i]]].y;
for(rg int j=1;j<=yy;j++)if(f[xx][j])ans++;
f[xx][yy]=1;d[mp[a[i]]].y--;
if(d[mp[a[i]]].x==l[mp[a[i]]].x&&d[mp[a[i]]].y<l[mp[a[i]]].y){
d[mp[a[i]]].x++,d[mp[a[i]]].y=m;
if(d[mp[a[i]]].x==r[mp[a[i]]].x)d[mp[a[i]]].y=r[mp[a[i]]].y;
}
else if(d[mp[a[i]]].y<1){
d[mp[a[i]]].x++,d[mp[a[i]]].y=m;
if(d[mp[a[i]]].x==r[mp[a[i]]].x)d[mp[a[i]]].y=r[mp[a[i]]].y;
}
}
printf("%d\n",ans);
}
}


### E.Buds Re-hanging

1、多出一个叶子节点，然后我们将该$$\rm bud$$接到一个叶子上，又可以减少一个叶子节点，总的来说叶子节点数不变

2、叶子节点数不变，然后我们将该$$\rm bud$$接到一个叶子上，减少一个叶子节点，总的来说叶子节点数减少$$1$$

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<time.h>
#include<set>
using namespace std;
#define rg register
#define ll long long
#define ull unsigned long long
#define lowbit(i) i&(-i)
#define pb(x) push_back(x)
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
const int maxn=2e5+10,mod=1e9+7;
int T,n,m,ans;bool used[maxn];
int cnt,pre[maxn*2],nxt[maxn*2],h[maxn];
pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
}
void dfs(int x,int fa){
int f=0;
for(rg int i=h[x];i;i=nxt[i])
if(pre[i]!=fa){
dfs(pre[i],x);
if(!used[pre[i]])f=1;
}
if(f&&x!=1)used[x]=1,m++;
if(x==1){
if(f)ans=-1;
else ans=0;
}
}
int main(){
while(T--){
dfs(1,0);printf("%d\n",ans+n-m*2);
for(rg int i=1;i<=n;i++)used[i]=0,h[i]=0;
}
}


### F.Points Movement

$$a_i$$是第$$i$$点的初始坐标

$$i$$个点至少要处理的区间是前$$v_i$$

1、假如当前考虑前$$i-1$$个点处理到了前$$k$$个区间，第$$i$$个点只处理到$$v_i$$，那么我们只需要向左移动就行了

2、假如当前考虑前$$i-1$$个点处理到了前$$k$$个区间，第$$i$$个点处理前$$t(v_i<t\leq v_{i+1})$$个区间，那么我们就有两种走法，先左移再向右移，或是先向右移再左移，这个地方的代价有些不好处理。因为对于每个$$t$$，向右的距离是固定的，两种走法分别计算一下最小值就行了

3、假如当前考虑前$$i-1$$个点处理到了前$$v_i$$个区间，那么第$$i$$个点就可以考虑只右移即可

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<time.h>
#include<set>
using namespace std;
#define rg register
#define ll long long
#define ull unsigned long long
#define lowbit(i) i&(-i)
#define pb(x) push_back(x)
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
const int maxn=2e5+10,mod=1e9+7;
int n,a[maxn],T,m,v[maxn],tot,cc[maxn];
ll f[2][maxn],g[maxn],ans=1e18;
struct oo{int l,r;}d[maxn],c[maxn];
bool cmp(oo a,oo b){return a.l<b.l;}
int main(){
while(T--){
sort(a+1,a+n+1);
sort(d+1,d+m+1,cmp);
for(rg int i=1;i<=m;i++){
int s=lower_bound(a+1,a+n+1,d[i].l)-a,t=upper_bound(a+1,a+n+1,d[i].r)-a-1;
if(s>t)c[++tot]=d[i],cc[tot]=d[i].r;
}
for(rg int i=1;i<=n;i++)v[i]=upper_bound(cc+1,cc+tot+1,a[i])-cc-1;
v[n+1]=tot;v[0]=0;f[0][0]=0;
for(rg int i=1;i<=tot;i++)f[0][i]=1e18;
for(rg int i=1;i<=n;i++){
f[i&1][0]=0;
for(rg int j=1;j<=tot;j++)f[i&1][j]=f[(i&1)^1][j],g[j]=1e18;
int now=2e9;
for(rg int j=v[i];j>v[i-1];j--){
now=min(now,c[j].r);
f[i&1][v[i]]=min(f[i&1][v[i]],f[(i&1)^1][j-1]+a[i]-now);
}
now=2e9;
for(rg int j=v[i];j>v[i-1];j--){
now=min(now,c[j].r);
g[v[i]]=min(g[v[i]],f[(i&1)^1][j-1]+2ll*(a[i]-now));
}
now=-2e9;
for(rg int j=v[i]+1;j<=v[i+1];j++){
now=max(now,c[j].l);
f[i&1][j]=min(f[i&1][j],f[i&1][v[i]]+2ll*(now-a[i]));
f[i&1][j]=min(f[i&1][j],g[v[i]]+now-a[i]);
f[i&1][j]=min(f[i&1][j],f[(i&1)^1][v[i]]+now-a[i]);
}
ans=min(ans,f[i&1][tot]);
}
printf("%lld\n",ans);
}
}

posted @ 2021-09-16 23:27  蒟蒻--lichenxi  阅读(69)  评论(0编辑  收藏  举报