2024.7.23 模拟赛6
模拟赛
T1 就是
T1 mod M
唐了一个半小时,最后 40min 才看出来,莫名挂
如果只考虑
那显然,我们只需要考虑什么时候能剩下一种。
只有在
既然都同余,就是任意两数的差的
思维不够严密,有
code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,a[N];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(int i=2;i<=n;i++)
{
if(a[i]==a[i+1]) continue;
if(__gcd(a[i]-a[1],a[i]-a[i-1])==1) return printf("2\n"),0;
}
printf("1\n");
return 0;
}
T2 Number of Multisets
其实挺简单的一道 dp,赛时唐。
想到去年 5K 口胡的题:
个正整数相加等于 ,求方案数。
正解类似分讨,
-
考虑包含
的方案,将 删掉,那么这类方案的数量为 。 -
考虑剩下的方案一定都不包含
,那么把 个数都减去 。方案数为 。
回来看这道题,我们仍是把所有方案划分成两类:包含
那么所有包含
code
#include<bits/stdc++.h>
using namespace std;
const int N = 3e3+5,mod = 998244353;
int n,k;
int f[N][N];
int main()
{
scanf("%d%d",&n,&k);
f[0][0]=1;
for(int i=1;i<=n;i++)
{
f[i][i]=1;
for(int j=i;j>=1;j--)
{
f[i][j]=(f[i-1][j-1]+f[i][j<<1])%mod;
}
}
printf("%d\n",f[n][k]);
return 0;
}
T3 Simultaneous Sugoroku
首先拿暴力和值域的部分分,都好拿。值域的其实有一点启发正解。
移动机器人其实和移动原点是等价的,假如我们把每次操作看成对原点移动,那么会有一个显然的性质:
- 关于原点对称的两个点在之后的操作中位置一定是对称的。
举例:假如原点移动到了
因此每次都有一半的数轴可以直接对称过去,也就是每次能删掉一部分。
我们可以用带权并查集维护对称次数,并查集的范围就是值域范围。
维护一个区间表示数轴上的实际范围,另一个维护以当前原点为中心左右延申的距离,每次合并较小的一半(启发式?)。
code
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+5,M = 1e6+6;
int n,m,a[N],b[N],ans[M];
int l,r,mid,L,R;
int fa[M];bool tag[M];
int find(int x)
{
if(fa[x]!=x)
{
int fx=fa[x];
fa[x]=find(fa[x]);
tag[x]^=tag[fx];
}
return fa[x];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
l=a[1]; r=a[n]; L=l; R=r;
for(int i=l;i<=r;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
if(l>0) l-=b[i],r-=b[i];
else l+=b[i],r+=b[i];
if(l<=0&&r>=0)
{
int x=R-r,fx=find(x);
ans[fx]=i;
if(-l<r)
{
for(int i=1;i<=-l;i++) fa[x-i]=x+i,tag[x-i]^=1;
L=x+1; l=1;
}
else
{
for(int i=1;i<=r;i++) fa[x+i]=x-i,tag[x+i]^=1;
R=x-1; r=-1;
}
}
}
for(int i=1;i<=n;i++)
{
int x=find(a[i]);
if(ans[x]) printf("Yes %d\n",ans[x]);
else printf("No %d\n",(r-R+x)*(tag[a[i]]?-1:1));
}
return 0;
}
T4 Triangles
这么多天第一次改到 T4!!!
还是 dp,每个顶点记录它向左上,右上,左 延伸的最大距离,首先考虑左和左上的限制如果想延伸一定在这个范围内。
然后对于满足这个限制的点看它向右上延伸距离是否满足。(说不太清,看图更不清)
只有三个方向都满足才能转移。定义
我们考虑每一个点的贡献,也就是每个点会有一个管辖范围。我们分别记它对后面的贡献,和前面哪些值会对它造成贡献。
我们开树状数组,查询
(下图:黑色是
记得反转求一次反向的三角形。
code
#include<bits/stdc++.h>
using namespace std;
const int N = 12005;
#define LL long long
int n,m;
string s[N];
int v1[N>>1][N],v2[N>>1][N],b[N];
LL ans;
struct BIT
{
int n,c[N];
void mdf(int x,int v)
{
for(;x;x-=(x&-x)) b[x]+=v;
}
int que(int x)
{
int res=0;
for(;x<=n;x+=(x&-x)) res+=b[x];//注意树状数组维护的是前缀和,而不是普通的后缀。
return res;
}
void clear()
{
for(int i=1;i<=n;i++) b[i]=0;
}
} c;
void reverse()
{
for(int i=1;i<=(n>>1);i++) swap(s[i],s[n-i+1]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
s[i][j]==0x5c?s[i][j]=0x2f:(s[i][j]==0x2f?s[i][j]=0x5c:0);
}
vector<int> p[N>>2];
vector<pair<int,int> >q[N>>2];
void work(int st)
{
for(int i=1;i<=n;i+=2)
{
c.clear();
for(int j=(i+st)%4,k=1,pre=1;j<=m;j+=4,k++)
{
v2[i][j]=s[i-1][j-1]==0x5c?v2[i-2][j-2]+1:0;
v1[i][j]=s[i-1][j+1]==0x2f?v1[i-2][j+2]+1:0;
s[i][j-1]!=0x2d?pre=k:pre;
p[k].clear(); q[k].clear();
p[k].push_back(k+v1[i][j]);
if(max(pre,k-v2[i][j])-1>0) q[max(pre,k-v2[i][j])-1].push_back(make_pair(k,-1));
if(k-1>0) q[k-1].push_back(make_pair(k,1));
}
for(int j=(i+st)%4,k=1;j<=m;j+=4,k++)
{
for(int h:p[k]) c.mdf(h,1);
for(pair<int,int> h:q[k]) ans+=h.second*c.que(h.first);
}
}
}
int main()
{
scanf("%d%d",&n,&m); c.n=n+m; n=(n<<1)-1; m=(m<<1)-1;
for(int i=0;i<=n;i++) getline(cin,s[i]),s[i]=' '+s[i];
work(0);
reverse();
work(s[1][1]==0x78?0:2);
printf("%lld\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端