专栏文章
题解:P14304 【MX-J27-T1】分块
P14304题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mini7w6s
- 此快照首次捕获于
- 2025/12/02 02:50 3 个月前
- 此快照最后确认于
- 2025/12/02 02:50 3 个月前
核心思想:找规律。
Part 1 暴力做法
直接按照题意模拟,可以获得 分(提交记录)。
这一部分非常简单,观察题目发现要找满足 并且 为 的因数的整数 的数量。直接看代码(如下)。
CPP#include<bits/stdc++.h>
#define int long long
#define INF 1145141919810
using namespace std;
int q,n;
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>q;//多测
while(q--){
cin>>n;
int ans=0;//统计
for(int i=1;i<=n;i++)
if(i%((int)sqrt(i))==0)
ans++;//符合条件
cout<<ans<<"\n";
}
return 0;
}
Part 2 正解观察
看着这道题就感觉有规律可循,所以我们直接弄一组 的数据。
跑出来:
CPP1
2
3
4
4
5
5
6
7
7
7
8
8
8
9
10
10
10
10
11
11
11
11
12
13
13
13
13
13
14
14
14
14
14
15
16
16
16
16
16
16
17
17
17
17
17
17
18
19
19
稍加观察,就可以发现一定规律并对其进行分组:
CPP1 2 3
4 4 5 5 6
7 7 7 8 8 8 9
10 10 10 10 11 11 11 11 12
13 13 13 13 13 14 14 14 14 14 15
16 16 16 16 16 16 17 17 17 17 17 17 18
19 19 ...
...
发现对于第 行(第 组),共有 个数字,其中前面 个为 ,中间 个为 ,最后一个为 。然后就可以差不多写出正解了。
Part 3 半个正解
我们需要确定 在第 行中的位置。显然,我们需要去除 在前面 行中的部分;运用高斯求和(对于前面 行包含的数字数量,可以表示为 )可知前面 行共有 个数字,所以需要让 变为 之后进行取模。然后按照上文去判断即可,注意如果是最后一个那么取模后的结果是 (可以发现,其实是不需要取模的,不过我就按照赛时取模的想法写出来了)。
如果 位于第 ,那么显然 有一个限定范围的区间。上面已经求出前面 行共有 个数字,前 行共有 个数字,所以 要满足 。这样就能找到 了。
代码如下。
CPP#include<bits/stdc++.h>
#define int long long
#define INF 1145141919810
using namespace std;
int q,n;
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>q;
while(q--){
cin>>n;
int ans=0,kkl=0;
for(int i=0;;i++){
int x=i;
if((x+1)*(x-1)<n&&n<=(x+2)*x){
ans=x;//找出 i,用 ans 表示
break;
}
}
int modu=(n-(ans+1)*(ans-1))%(ans*2+1);//位置
if(modu==0)kkl=3;
else if(modu<=ans)kkl=1;
else kkl=2;//判断
cout<<(ans-1)*3+kkl<<"\n";//输出
}
return 0;
}
Part 4 正解
我们发现 Part 3 时间复杂度太高,达到了 (因为 大概在 级别),而我们发现, 大概就在 附近。所以可以优化。
一个无脑做法:直接从 开始往两边扫。
……
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...