2024.7.29模拟赛11
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模拟赛78.2024.7.26模拟赛89.2024.7.27模拟赛910.2024.7.28 模拟赛10
11.2024.7.29模拟赛11
12.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 FATE
还挺水。
首先求出最短路长度,然后从
code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5,mod = 1e9+7;
#define LL long long
int n,m;
int s,t;
int head[N],tot;
LL f[N][2];
struct E {int u,v;} e[N<<1];
inline void add(int u,int v) {e[++tot]={head[u],v}; head[u]=tot;}
int d[N];
bool vs[N];
void dj(int s)
{
memset(d,0x3f,sizeof(d));
priority_queue<pair<int,int> > q;
d[s]=0; q.push(make_pair(0,s));
while(!q.empty())
{
int u=q.top().second; q.pop();
if(vs[u]) continue;
vs[u]=1;
for(int i=head[u];i;i=e[i].u)
{
int v=e[i].v;
if(!vs[v]&&d[v]>d[u]+1)
{
d[v]=d[u]+1;
q.push(make_pair(-d[v],v));
}
}
}
}
LL dfs(int u,int k)
{
if(f[u][k]) return f[u][k];
if(u==s) return (k==0);
LL res=0;
for(int i=head[u];i;i=e[i].u)
{
int v=e[i].v;
if(k&&d[v]==d[u]) res=(res+dfs(v,0))%mod;
else if(d[v]==d[u]-1) res=(res+dfs(v,k))%mod;
}
return f[u][k]=res;
}
int main()
{
// freopen("Fate9.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
int x,y; scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
dj(s);
printf("%lld\n",dfs(t,1));
return 0;
}
T2 Fishing
思维题吧,好像能用模拟退火骗分。
考虑鱼之间的相对运动,每次定住一条鱼,令网的最左端在这条鱼上,其他鱼相对运动。网一定在某个时刻鱼刚好出边界或进边界时最优,都是
code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e3+5;
const double inf=1e-9;
#define LL long long
int n,a,w[N],x[N],v[N],ans;
map<double,int> mp;
int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d%d",&n,&a);
for(int i=1;i<=n;i++) scanf("%d%d%d",&w[i],&x[i],&v[i]);
for(int i=1;i<=n;i++)
{
int res=w[i]; mp.clear();
for(int j=1;j<=n;j++)
{
if(j==i) continue;
if(v[i]==v[j])
{if(x[j]>=x[i]&&x[j]<=x[i]+a) res+=w[j];}
else
{
double tl=1.0*(x[i]-x[j])/(v[j]-v[i]);
double tr=1.0*(x[i]+a-x[j])/(v[j]-v[i]);
if(tr-tl<inf) swap(tl,tr);
if(tr>=0)
{
tl=max(0.0,tl);
mp[tl]+=w[j];
mp[tr+inf]-=w[j];
}
}
}
ans=max(ans,res);
if(!mp.empty())
for(pair<double,int> i:mp)
res+=i.second,ans=max(ans,res);
}
printf("%d\n",ans);
return 0;
}
T3 ≥ K
非常巧妙的一道题,我们考虑插空法。
首先排序,左右指针从两端开始扫。
对于一个较小的数,它必须放在两个大于等于
所以我们右指针扫,每扫到一个大于等于的数会将可填的位置
每次统计方案数就好啦。
code
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 2e5+5,mod = 998244353;
int n,k,a[N],cnt[N];
LL ans,p[N];
LL qpow(LL a,int b)
{
LL res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod; b>>=1;
}
return res;
}
int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d%d",&n,&k);
p[1]=1; for(int i=2;i<=n;i++) p[i]=p[i-1]*i%mod;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+1+n);
int l=1,r=n,t=1; ans=1;
while(l<=r)
{
while(1ll*a[l]+a[r]>=1ll*k&&l<r) ans=(ans*t)%mod,r--,t++;
ans=(ans*t)%mod; t--; l++;
}
// printf("%lld\n",ans);
for(int i=1,j=1;i<=n;j=i)
{
while(a[j]==a[j+1]) j++;
cnt[++cnt[0]]=j-i+1; i=j+1;
}
for(int i=1;i<=cnt[0];i++)
{
if(cnt[i]>1)
ans=(ans*qpow(p[cnt[i]],mod-2))%mod;
}
printf("%lld\n",ans);
return 0;
}
T4 Tourism
珂朵莉树。
转化题意,给出
首先树剖把树上问题转化为区间问题,然后考虑如何维护区间信息。
对于子图大小,我们可以用染色的方式,每次将两点间的路径染成同一颜色(用更新时间作为颜色),设第
这样随右端点的右移,每次将
当我们染到
染色就是维护颜色段区间推平操作,用珂朵莉维护。(码量还挺小)
code
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
#define fi first
#define se second
int n,m,q,a[N],ans[N];
int head[N],tot;
struct E {int u,v;} e[N<<1];
inline void add(int u,int v) {e[++tot]={head[u],v}; head[u]=tot;}
vector<pair<int,int> > Q[N];
struct BIT
{
int c[N];
inline void mdf(int x,int v) {for(;x<=m;x+=(x&-x)) c[x]+=v;}
inline int que(int x) {int res=0; for(;x;x-=(x&-x)) res+=c[x]; return res;}
} bit;
struct ODT
{
struct node
{
int l,r; mutable int v;
bool operator <(const node &x) const {return l<x.l;}
}; set<node> s;
inline auto get(int x)
{
auto it=s.upper_bound({x,N,0}); it--;
if(it->l==x) return it;
int l=it->l,r=it->r,v=it->v;
s.erase(it),s.insert({l,x-1,v});
return s.insert({x,r,v}).first;
}
inline void change(int l,int r,int v)
{
auto end=get(r+1),begin=get(l);
for(auto it=begin;it!=end;++it)
bit.mdf(it->v,-(it->r-it->l+1));
s.erase(begin,end);
s.insert({l,r,v}),bit.mdf(v,r-l+1);
}
} odt;
namespace TCS
{
int dep[N],sz[N],son[N],dfn[N],cnt,rk[N],fa[N],top[N];
void dfs1(int u,int f)
{
dep[u]=dep[f]+1; fa[u]=f; son[u]=-1; sz[u]=1;
for(int i=head[u];i;i=e[i].u)
{
int v=e[i].v; if(v==f) continue;
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!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
void change(int x,int y,int t)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
odt.change(dfn[top[x]],dfn[x],t);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
odt.change(dfn[x],dfn[y],t);
}
}; using namespace TCS;
int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d%d%d",&n,&m,&q);
odt.s.insert({1,n,1}); bit.mdf(1,n);
for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs1(1,0); dfs2(1,1);
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
for(int i=1,l,r;i<=q;i++)
{
scanf("%d%d",&l,&r);
if(l==r) ans[i]=1; else Q[r].push_back({l,i});
}
for(int i=2;i<=m;i++)
{
change(a[i-1],a[i],i);
for(pair<int,int> now:Q[i]) ans[now.se]=n-bit.que(now.fi);
}
for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】