前言
- 比赛链接。
今天题好难啊,大多数人 T2、T4 改不动都不改了,下午 miaomiao
进来和我们说模拟赛改不动的题可以不改。
部分分给的也很少。
T1 Mortis
\(O(n)\) 桶排序,知道每个数最后应该去哪,那么对于需要交换的只有三种情况:
- 二者错排,交换一次。
- 三者错排,交换两次。
- 四者错排,交换三次。
当然这几种情况优先处理第一种,其次第二种,最后第三种,由此处理即可,最后总的复杂度是线性的。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=2e5+10;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char c=getchar();
for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x)
{if(x>9)wt(x/10);putchar((x%10)+'0');}
template<typename Tp> inline void write(Tp x)
{if(x<0)putchar('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);}
int n,a[N],sum[5],b[N],cnt[5][5],ans,tot;
signed main()
{
read(n);
for(int i=1;i<=n;i++)
{
read(a[i]);
sum[a[i]]++;
}
for(int i=1,pre=0;i<=4;i++)
{
for(int j=1;j<=sum[i];j++)
b[pre+j]=i;
pre+=sum[i];
}
for(int i=1;i<=n;i++)
if(a[i]!=b[i])
{
tot++;
cnt[a[i]][b[i]]++;
}
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(i!=j)
{
int s=min(cnt[i][j],cnt[j][i]);
ans+=s,tot-=s<<1;
cnt[i][j]-=s,cnt[j][i]-=s;
}
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(i!=j) for(int k=1;k<=4;k++)
if(i!=k&&j!=k)
{
int s=min({cnt[i][j],cnt[j][k],cnt[k][i]});
ans+=s<<1,tot-=(s<<1)+s;
cnt[i][j]-=s,cnt[j][k]-=s,cnt[k][i]-=s;
}
write(ans+tot/4*3);
}
T2 生活在hzoi上
不会。
T3 嘉然今天吃什么
-
部分分 \(10pts\):每个区间都跑一次 \(01trie\),复杂度 \(O(n^2\log v)\)。
-
正解:
求出 \(dfs\) 序,可以转化为序列问题,点 \(x\) 对应区间 \([1,in_x),(out_x,n)\)
发现对于大多数的区间都是全局最大值,可以处理出达成这个答案的是哪两个点,这是 \(01trie\) 板子。
然后对于整棵树上,只有 \(1\to lca,lca\to u,lca\to v\) 这几段路径是不能使用全局最大值的,又发现这是一条链,链是好处理的,因为 \(fa_x\) 对应区间一定包含在 \(x\) 对应区间内,用两个指针维护就行了。
点击查看代码
#include<bits/stdc++.h> #define ll long long #define endl '\n' #define sort stable_sort using namespace std; const int N=5e5+10,M=3e7+10; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=true; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0; for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);} template<typename Tp> inline void wt(Tp x) {if(x>9)wt(x/10);putchar((x%10)+'0');} template<typename Tp> inline void write(Tp x) {if(x<0)putchar('-'),x=~x+1;wt(x);} template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar(' ');write(y...);} int n,tot,u,v,lca,top1,top2,fa[N],in[N],out[N],dep[N]; ll mx_a,maxx,mx,a[N],b[N],ans[N]; bool vis[N]; vector<int>e[N]; struct trie { int tot,t[M][2],pos[M]; void insert(int id) { ll x=a[id]; int p=0; for(int i=__lg(mx_a),c;i>=0;i--) { c=(x>>i)&1; if(!t[p][c]) t[p][c]=++tot; p=t[p][c]; } pos[p]=id; } int ask(ll x) { int p=0; for(int i=__lg(mx_a),c;i>=0;i--) { c=(x>>i)&1; if(t[p][!c]) p=t[p][!c]; else p=t[p][c]; } return pos[p]; } void clear() { for(int i=0;i<=tot;i++) t[i][0]=t[i][1]=pos[i]=0; tot=0; } }T; void dfs(int x,int dis) { in[x]=++tot,dep[x]=dis; for(int y:e[x]) dfs(y,dis+1); out[x]=tot; } int lca_(int x,int y) { if(dep[x]<dep[y]) swap(x,y); for(;dep[x]!=dep[y];x=fa[x]) vis[x]=1; for(;x!=y;x=fa[x],y=fa[y]) vis[x]=vis[y]=1; return x; } void dfs(int x,int goal,int l,int r) { if(!x) return ; for(int s;l<=in[x]-1;l++) { T.insert(l); s=T.ask(a[l]); mx=max(mx,a[l]^a[s]); } for(int s;r>=out[x]+1;r--) { T.insert(r); s=T.ask(a[r]); mx=max(mx,a[r]^a[s]); } ans[x]=mx; if(x==goal) return ; for(int y:e[x]) if(vis[y]) { dfs(y,goal,l,r); break; } } signed main() { read(n); for(int i=2;i<=n;i++) { read(fa[i]); e[fa[i]].push_back(i); } for(int i=1;i<=n;i++) { read(a[i]); mx_a=max(mx_a,a[i]); } for(int i=1,j;i<=n;i++) { T.insert(i); j=T.ask(a[i]); if((a[i]^a[j])>maxx) { maxx=a[i]^a[j]; u=i,v=j; } } dfs(1,1); memcpy(b,a,sizeof(a)); for(int i=1;i<=n;i++) a[in[i]]=b[i]; lca=lca_(u,v); for(int i=lca;i;i=fa[i]) vis[i]=1; for(int i=u;i!=lca;i=fa[i]) top1=i; for(int i=v;i!=lca;i=fa[i]) top2=i; T.clear(); mx=0; dfs(1,lca,1,n); T.clear(); mx=0; dfs(top1,u,1,n); T.clear(); mx=0; dfs(top2,v,1,n); for(int i=1;i<=n;i++) write(vis[i]?ans[i]:maxx),puts(""); }
T4 APJifengc
不会。
总结
不知道说点什么,只是好想秦皇岛啊。
附录
题目背景比较魔怔,看题目名称也能看出来。
标签:write,22,int,void,Tp,2024,read,inline,集训 From: https://www.cnblogs.com/Charlieljk/p/18353897