2024.7.26模拟赛8
1.2024.7.18模拟赛12.2024.7.19模拟赛23.2024.7.20模拟赛34.2024.7.21模拟赛45.2024.7.22模拟赛56.2024.7.23 模拟赛67.2024.7.25模拟赛7
8.2024.7.26模拟赛8
9.2024.7.27模拟赛910.2024.7.28 模拟赛1011.2024.7.29模拟赛1112.2024.7.31模拟赛1213.2024.8.1 模拟赛1314.2024.8.6 模拟赛 1415.2024.8.7 模拟赛 1516.2024.8.8模拟赛1617.2024.8.10模拟赛1718.2024.8.18 模拟赛 2219.2024.8.19 模拟赛 2420.小集训21.2024.9.23 模拟赛 CSP 322.2024.9.24 模拟赛 CSP423.2024.9.25 模拟赛 多校24.2024.9.27 模拟赛 CSP525.2024.9.28 模拟赛 CSP626.2024.9.30 模拟赛 CSP727.2024.10.7 模拟赛 多校328.2024.?.?? 模拟赛 ???模拟赛
抽象比赛,含金量最高的是题目背景?
好像还是连续的。。。
T1 Same Integers
题目背景
签到题,因为只有加操作,目标是将两个较小的数加成最大的。
根据差的奇偶判断能否加二得到,如果不能先加一调一下。(简单题,题解抽象一点也没事吧)
code
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
LL a[3],ans;
int main()
{
for(int i=0;i<3;i++) scanf("%lld",&a[i]);
sort(a,a+3);
int x=a[2]-a[0],y=a[2]-a[1];
if((x&1) && (y&1)) ans=(x-1>>1)+(y-1>>1)+1;
else if(x&1) ans=(y>>1)+(x+1>>1)+1;
else if(y&1) ans=(x>>1)+(y+1>>1)+1;
else ans=(x>>1)+(y>>1);
printf("%lld\n",ans);
return 0;
}
T2 Qpwoeirut and Vertices
题目背景
首先要想到建立最小生成树,因为我们只在乎使某个连通块第一次被连通的边,后面再加边都可以忽略,所以最终建出的一定是一棵树。
然后考虑答案是什么,将边的编号赋成边权,那么使
使
路径最大值可以用树剖 + ST 表,区间最值也用
正解是新科技:克鲁斯卡尔重构树。
不同于最小生成树,克鲁斯卡尔重构树是对于每一条边建一个虚点,点权等于原边权,虚点向原边的两个端点所在连通块的代表点连边。
因为加边按顺序,所以这样重构的树(森林)从根到叶子的权值一定是单调不上升的,那么使两点连通的最小权值就是重构树离他们最近的祖先的点权。
LCA + ST 表即可。
code(ST + ST)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int t;
int n,m,q;
struct K {int u,v,w;} k[N<<1];
inline bool cmp(const K &x,const K &y) {return x.w<y.w;}
int head[N],tot;
struct E {int u,v,w;} e[N<<1];
inline void add(int u,int v,int w) {e[++tot]={head[u],v,w}; head[u]=tot;}
struct BCJ
{
int fa[N];
inline void init() {for(int i=1;i<=n;i++) fa[i]=i;}
inline int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}
} bcj;
int dfn[N],dep[N],son[N],sz[N],cnt,rk[N],fa[N],top[N],a[N];
void dfs1(int u,int f)
{
dep[u]=dep[f]+1; son[u]=-1; sz[u]=1; fa[u]=f;
for(int i=head[u];i;i=e[i].u)
{
int v=e[i].v;
if(v==f) continue;
a[v]=e[i].w;
dfs1(v,u);
sz[u]+=sz[v];
if(son[u]==-1||sz[son[u]]<sz[v]) son[u]=v;
}
}
void dfs2(int u,int t)
{
top[u]=t; dfn[u]=++cnt; rk[cnt]=u;
if(son[u]==-1) return;
dfs2(son[u],t);
for(int i=head[u];i;i=e[i].u)
{
int v=e[i].v;
if(v!=son[u]&&v!=fa[u]) dfs2(v,v);
}
}
struct ST1
{
int st[30][N];
inline void bui()
{
for(int i=1;i<=n;i++) st[0][i]=a[rk[i]];
for(int i=1;i<=25;i++)
for(int j=1;j+(1<<i)-1<=n;j++)
st[i][j]=max(st[i-1][j],st[i-1][j+(1<<i-1)]);
}
inline int que(int l,int r)
{
int k=__lg(r-l+1);
return max(st[k][l],st[k][r-(1<<k)+1]);
}
} st;
int Que(int x,int y)
{
int res=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=max(res,st.que(dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(x==y) return res;
if(dep[x]>dep[y]) swap(x,y);
res=max(res,st.que(dfn[x]+1,dfn[y]));
return res;
}
struct ST2
{
int st[30][N];
inline void bui()
{
for(int i=1;i<n;i++) st[0][i]=Que(i,i+1);
for(int i=1;i<=25;i++)
for(int j=1;j+(1<<i)-1<n;j++)
st[i][j]=max(st[i-1][j],st[i-1][j+(1<<i-1)]);
}
inline int que(int l,int r)
{
int k=__lg(r-l+1);
return max(st[k][l],st[k][r-(1<<k)+1]);
}
} st2;
void init()
{
cnt=0; tot=0;
memset(head,0,sizeof(head));
}
int main()
{
// freopen("lagrange3.in","r",stdin);
// freopen("o1.out","w",stdout);
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d%d",&n,&m,&q); bcj.init();
for(int i=1;i<=m;i++)
{
int x,y; scanf("%d%d",&x,&y);
k[i]={x,y,i};
}
for(int i=1;i<=m;i++)
{
int fx=bcj.find(k[i].u),fy=bcj.find(k[i].v);
if(fx!=fy) bcj.fa[fx]=fy,add(k[i].u,k[i].v,k[i].w),add(k[i].v,k[i].u,k[i].w);
}
dfs1(1,0); dfs2(1,1);
st.bui(); st2.bui();
while(q--)
{
int x,y; scanf("%d%d",&x,&y);
if(x==y) printf("0\n");
else printf("%d\n",st2.que(x,y-1));
}
}
return 0;
}
code(重构树)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int t,q,n,m;
struct K {int u,v;} k[N];
int head[N],tot,num,w[N],fa[30][N],dep[N],a[N];
struct E {int u,v;} e[N<<1];
inline void add(int u,int v) {e[++tot]={head[u],v}; head[u]=tot;}
struct BCJ
{
int fa[N];
void bui()
{
for(int i=1;i<=(n<<1);i++) fa[i]=i;
}
inline int find(int x)
{
if(x!=fa[x]) fa[x]=find(fa[x]);
return fa[x];
}
} bcj;
void dfs(int u,int f)
{
dep[u]=dep[f]+1; fa[0][u]=f;
for(int i=1;i<=20;i++) fa[i][u]=fa[i-1][fa[i-1][u]];
for(int i=head[u];i;i=e[i].u)
{
int v=e[i].v; if(v==f) continue;
dfs(v,u);
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;i--) if(dep[fa[i][x]]>=dep[y]) x=fa[i][x];
if(x==y) return x;
for(int i=20;i>=0;i--) if(fa[i][x]!=fa[i][y]) x=fa[i][x],y=fa[i][y];
return fa[0][x];
}
struct ST
{
int st[20][N];
void bui()
{
for(int i=1;i<n;i++) st[0][i]=a[i];
for(int i=1;i<=20;i++)
for(int j=1;j<n;j++)
st[i][j]=max(st[i-1][j],st[i-1][j+(1<<i-1)]);
}
int que(int l,int r)
{
int k=__lg(r-l+1);
return max(st[k][l],st[k][r-(1<<k)+1]);
}
} st;
int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&q); tot=0,num=n;
for(int i=1;i<=m;i++) scanf("%d%d",&k[i].u,&k[i].v);
for(int i=1;i<=n<<1;i++)
{
bcj.fa[i]=i; head[i]=0; dep[i]=0;
}
for(int i=1;i<=m;i++)
{
int fx=bcj.find(k[i].u),fy=bcj.find(k[i].v);
if(fx==fy) continue;
bcj.fa[fx]=bcj.fa[fy]=++num; w[num]=i;
add(num,fx); add(num,fy);
}
for(int i=num;i>=n+1;i--)
if(!dep[i]) dfs(i,0);
for(int i=1;i<n;i++)
{
int d=lca(i,i+1);
a[i]=w[d];
}
st.bui();
while(q--)
{
int l,r; scanf("%d%d",&l,&r);
if(l==r) printf("%d ",0);
else printf("%d ",st.que(l,r-1));
}
printf("\n");
}
return 0;
}
T3 Subset Sum Game
咕咕咕。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端