网站建设公司出路,网站建设维护岗位,河南最新消息,网站图片做cdn[ABC206E] Divide Both 解题记录 题意简述
给定整数 L , R L,R L,R#xff0c;求满足以下条件的数对 ( x , y ) (x,y) (x,y) 的数量。 x , y x,y x,y 不互质 x ∤ y x \nmid y x∤y 且 y ∤ x y \nmid x y∤x 题目分析
正难则反#xff0c;考虑用所有的满足第一条性质的…[ABC206E] Divide Both 解题记录 题意简述
给定整数 L , R L,R L,R求满足以下条件的数对 ( x , y ) (x,y) (x,y) 的数量。 x , y x,y x,y 不互质 x ∤ y x \nmid y x∤y 且 y ∤ x y \nmid x y∤x 题目分析
正难则反考虑用所有的满足第一条性质的数对的数量减去不满足第二条性质的数量。 容易想到如果不考虑第二条性质那么我们可以枚举因子 i ∈ [ 2 , r ] i \in [2,r] i∈[2,r]求解出 [ l , r ] [l,r] [l,r] 区间内的 i i i 的倍数的个数 s s s然后用加法原理两两配对累加到答案中。 如何求解 s s s 不妨设 x k × i b xk \times ib xk×ib则 i ∣ ( x − b ) i \mid (x-b) i∣(x−b)即对于每个 j ∈ [ 1 , k ] j \in [1,k] j∈[1,k] 都有 i ∣ ( x − b − j × i ) i \mid (x-b-j \times i) i∣(x−b−j×i)一共 k k k 个数而这个 k k k 就是 ⌊ r i ⌋ \lfloor\frac{r}{i}\rfloor ⌊ir⌋对于 k k k 个数字两两配对即可求解出 s k × ( k − 1 ) 2 s\frac{k \times (k-1)}{2} s2k×(k−1)。但是这样会有重复如当 i 2 , 3 , 6 i2,3,6 i2,3,6 时均会有数对 ( 6 , 12 ) (6,12) (6,12)这个时候就需要我们标记了。可以设 c n t i cnt_i cnti 表示 i i i 的质因子的个数如果 c n t i cnt_i cnti 为偶数就减去当前贡献否则加上。那么我们对于 i 2 , 3 i2,3 i2,3 的时候加上了 ( 6 , 12 ) (6,12) (6,12) 的贡献在 i 6 i6 i6 的时候就会减去一个这样就保证了贡献不会重复不清楚的可以手模。 最后减去不满足第二条限制的贡献对于每个因子 i ∈ [ 2 , r ] i \in [2,r] i∈[2,r]减去 [ l , r ] [l,r] [l,r] 中除 i i i 外 i i i 的倍数即 ⌊ r i ⌋ − 1 \lfloor\frac{r}{i}\rfloor -1 ⌊ir⌋−1。 AC Code
#includebits/stdc.h
#define arrout(a,n) rep(i,1,n)std::couta[i]
#define arrin(a,n) rep(i,1,n)std::cina[i]
#define rep(i,x,n) for(int ix;in;i)
#define dep(i,x,n) for(int ix;in;i--)
#define erg(i,x) for(int ihead[x];i;ie[i].nex)
#define dbg(x) std::cout#x:x
#define mem(a,x) memset(a,x,sizeof a)
#define all(x) x.begin(),x.end()
#define arrall(a,n) a1,a1n
#define PII std::pairint,int
#define m_p std::make_pair
#define u_b upper_bound
#define l_b lower_bound
#define p_b push_back
#define CD const double
#define CI const int
#define int long long
#define il inline
#define ss second
#define ff first
#define itn int
CI N1e65;
int l,r,ans,cnt[N];
void init() {rep(i,2,r) {if(cnt[i]!0) {continue;}for(int ji;jr;ji) {if(cnt[j]0) {cnt[j];}}for(int ji*i;jr;ji*i) {cnt[j]-1;}}
}
signed main() {std::cinlr;init();rep(i,2,r) {if(cnt[i]0) {continue;}int sr/i-(l-1)/i;ss*(s-1)/2;if(cnt[i]%2) {anss;} else {ans-s;}}rep(i,std::max(l,2ll),r) {ans-r/i-1;}std::coutans*2;return 0;
}