Atcoder Beginner Contest 367
A.Shout Everyday
给你
小时制下的 三个时刻,问 是否在 范围内
考虑到先将
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b,c;
cin>>a>>b>>c;
if(c<b) c+=24;
while(a<=c){
// cout<<a<<" in "<<b<<" "<<c<<endl;
if(a>=b and a<=c){
cout<<"No"<<endl;
return 0;
}
a+=24;
}
cout<<"Yes"<<endl;
}
B.Cut .0
给定一个小数,去除多余的后导零或小数点
比第一题水,不说了
#include<bits/stdc++.h>
using namespace std;
int main(){
string x;
cin>>x;
for(int i=x.length()-1;i>=0;--i){
if(x[i]=='.'){
x.pop_back();
break;
}
if(x[i]!='0') break;
x.pop_back();
}
cout<<x<<endl;
}
C.Enumerate Sequences
按字典序输出所有满足条件的,长度为
的序列
显然应该是爆搜
#include<bits/stdc++.h>
using namespace std;
int a[9];
int n,k;
int r[9];
void dfs(int now,int nowsum){
if(now>n){
if(nowsum%k==0){
for(int i=1;i<=n;++i){
cout<<a[i]<<" ";
}
cout<<endl;
}
return;
}
for(int i=1;i<=r[now];++i){
a[now]=i;
dfs(now+1,nowsum+i);
}
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>r[i];
}
dfs(1,0);
}
D.Pedometer
顺时针给你一个环,告诉你环上各边的权值
定义
为从 顺时针走到 的路径长 请你求出所有满足
的点对数量
显然不能每次都改变整个
首先先来模拟一下,先考虑暴力,每次枚举出发点,开一个数组
2 1 4 3
i dis
1 0 2 3 7
2 8 0 1 5
3 7 9 0 4
可以发现,每当我们将
- 将
加上总路径和(其实就是绕了一圈) - 将整个
数组减去
发现第二步实际上是可以优化的,因为这道题是取模操作,方便我们优化. 注意到若
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,sum;
int a[200001],r[1000001],pres[200002],opres[200002];
signed main(){
scanf("%lld %lld",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
sum+=a[i];
}
for(int i=1;i<=n-1;++i){
pres[i]=pres[i-1]+a[i];
opres[i]=pres[i];
r[pres[i]%m]++;
}
r[0]++;
int ans=0,rm=m,msum=0;
for(int i=1;i<=n;++i){
m+=opres[i]-msum;
msum+=pres[i]-msum;
r[pres[i==1?n:i-1]%rm]--;
pres[i==1?n:i-1]+=sum;
r[pres[i==1?n:i-1]%rm]++;
ans+=r[msum%rm];
}
cout<<ans-n<<endl;
}
E.Permute K times
给定长度为
的序列 ,其中 ,对序列 执行 次下列操作:
- 同时将全部
赋值为 求最终的序列
好题。
この問題は、 ダブリング と呼ばれるテクニックで解くことができます
我并不知道 ダブリング 是啥算法,但是我猜大抵是倍增罢
注意到我们每次在
又注意到
定义
初始化
但是有了这个东西还不够,因为它让我们求恰好
写到这基本就能想到了,搞一个二进制分解就行了
其实本来想暴力建图弄一个内向基环树的,因为在树上直接维护环信息,到最后直接取模
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k;
int p[61][200001],a[200001],x[200001];
signed main(){
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>p[0][i];
}
for(int i=1;i<=n;++i){
cin>>a[i];
}
for(int i=1;i<=60;++i){
for(int j=1;j<=n;++j){
p[i][j]=p[i-1][p[i-1][j]];
}
}
for(int i=1;i<=n;++i){
x[i]=i;
}
for(int i=0;i<=60;++i){
if(k&1){
for(int j=1;j<=n;++j){
x[j]=p[i][x[j]];
}
}
k>>=1;
}
for(int i=1;i<=n;++i){
cout<<a[x[i]]<<" ";
}
cout<<endl;
}
F.Rearrange Query
给你两个序列
每次询问给定
,判断是否满足下列条件
可以通过重排与 匹配
当
设计一个哈希值,考虑每次直接
异或哈希做不到给每个元素都赋不同的值,因为它总共就只有
假如我们真的用原数列做哈希的话,出题人随便就给卡了,因为即便是和哈希,哈希冲突的概率还是太高. 因此考虑开一个 map,把数字离散化,均匀分布到
此外,直接处理前缀和即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int p=141592653589;
int n,q;
int a[200001],b[200001],val[200001],sum1[200001],sum2[200001];
signed main(){
cin>>n>>q;
ios::sync_with_stdio(false);
srand(time(0));
for(int i=1;i<=n;++i){
val[i]=(rand()*1ll*rand())%(p-1)+1;
}
for(int i=1;i<=n;++i){
cin>>a[i];
a[i]=val[a[i]];
sum1[i]=sum1[i-1]+a[i];
}
for(int i=1;i<=n;++i){
cin>>b[i];
b[i]=val[b[i]];
sum2[i]=sum2[i-1]+b[i];
}
for(int i=1;i<=q;++i){
int l,r,L,R;
cin>>l>>r>>L>>R;
if((sum1[r]-sum1[l-1])%p!=(sum2[R]-sum2[L-1])%p) cout<<"No\n";
else cout<<"Yes\n";
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!