0%

思路讲解

ABC-383-D - 9 Divisors 

其实这个约数个数定理是显然的

你想p1的指数有0e10~e_1也就是e1+1e_1+1种选择,同理,每种都有ek+1e_k+1种选择

那么根据乘法原理,约束个数也就是 d(n)=(e1+1)(e2+1)(ek+1)d(n)=(e_1+1)(e_2+1)…(e_k+1)

当然喽,只有素因子可以这么玩,非素因子这么玩可能会有重复


当然这道题目关键点不在上面。

N=p1e1p2e2N=p_1^{e_1}p_2^{e_2} 由题意可得,e1为偶数,e2也为偶数。所以其实400数要求是完全平方数,而且是只由两个素因子构成。那么其实也就是要求平方数由两个素因子组成。

哈哈,其实这种也是有点套路,一般来说这种都是直接枚举素因子的

我们用埃氏筛筛出所有1e6以内的素数,存储在primes中。然后就枚举就完了。

AC代码

心路历程(WA,TLE,MLE……)

这个ll是非常需要的,写成int以后就TLE了,可能是因为溢出了。

1
2
3
4
5
6
7
8
9
10
11
12
13
for(int i=0;i<primes.size();++i){
ll p=primes[i];
for(ll j=p;j<=MAXN-10;j*=p){
for(int k=i+1;k<primes.size();++k){
ll pk=primes[k];
if(pk*j>MAXN-10) break;
for(ll p_k=pk;p_k<=MAXN-10;p_k*=pk){
if(p_k*j>MAXN-10) break;
fitNum.pb(p_k*j);
}
}
}
}

思路讲解

赛时想到思路了,也写出来了,但是死活都会WA四个点。

这种问题一般就是转化成二进制想,其实2^a就是二进制下右移a位。

最后靠AI手写了个二分的开方程序过了,这个是在有点离谱,现在在想我的程序为什么会WA。

找到一个博客,说sqrt是有点问题。

https://codeforces.com/blog/entry/107717

利用sqrtl就过了,离谱,floor(sqrt(i))就不行。

其实sqrtl其实是传入参数为long double,那么其实还是精度问题。我直接这么调用其实还有一个自动向下的隐式转换。

https://en.cppreference.com/w/c/numeric/math/sqrt

AC代码

https://atcoder.jp/contests/abc400/submissions/64576953

心路历程(WA,TLE,MLE……)

666

思路讲解

双段队列优化,让cnt比较低的先走,这样子保证可以被比较好的剪枝

也可以使用堆优化,比双段队列deque稍慢,但也还行。

AC代码

https://atcoder.jp/contests/abc400/submissions/64555057

https://atcoder.jp/contests/abc400/submissions/64575744

心路历程(WA,TLE,MLE……)

思路讲解

原来是想用zkw线段树写P1253,但是zkw写懒标记顺序不可调换的题目还是比较难的,我们要顺势而为,这个写zkw就是为了简单,写着反而复杂就干脆不写了。

参考讲解

https://www.cnblogs.com/Judge/p/9514862.html

https://www.cnblogs.com/zsc985246/p/16112689.html

讲解没有细讲的zkw线段树求最大值转化方法

这个线段树(求最大值的话)子节点里装的值需要不断+母节点的值+母母节点的值+…+根节点的值才是真实的值,这样子可以比较好的实现bottom-up修改。

zkw线段树加法示意图

加法用这套东西是没有问题的,但容易发现,覆盖用这套操作会稍微有点问题。

https://blog.csdn.net/weixin_43960287/article/details/108246164

image

看过了,这个问题基本上可以说无解了。

AC代码

心路历程(WA,TLE,MLE……)

思路讲解

参考题解以及视频讲解

【数据结构扩展(二) --线段树 (普通+zkw)】 【精准空降到 18:48】 https://www.bilibili.com/video/BV1gy4y1D7dx/?share_source=copy_web&vd_source=6ca0bc05e7d6f39b07c1afd464edae37&t=1128

https://www.cnblogs.com/Judge/p/9514862.html

image

AC代码

https://leetcode.cn/problems/range-sum-query-mutable/submissions/618952189

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class NumArray {
public:
typedef long long ll;
vector<ll> tree;
ll N;
void update(int index, int val) {
ll diff=val-tree[index+N];
for(int i=index+N;i>0;i>>=1){
tree[i]+=diff;
}
}
int sumRange(int left, int right) {
ll res=0;
for(int i=left+N,j=right+N;i<=j;i>>=1,j>>=1){
if(i%2==1) res+=tree[i++];
if(j%2==0) res+=tree[j--];
}
return res;
}
NumArray(vector<int>& nums) {
// for(int i=0;i<nums.size();++i){
// lnum.push_back(nums[i]);
// }
N=nums.size();
tree.resize(2*N+5,0);
for(int i=0;i<nums.size();++i){
update(i,nums[i]);
}
// for(int i=0;i<tree.size();++i){
// cout<<i<<": "<<tree[i]<<"\n";
// }
}

};

心路历程(WA,TLE,MLE……)