思路讲解
你最少可以干多少活=总共要干多少活-之前的人干了多少活-后面的人最多干多少活
AC代码
1 |
|
你最少可以干多少活=总共要干多少活-之前的人干了多少活-后面的人最多干多少活
1 | #include <iostream> |
其实这题这题知道结论很简单
1,2,3,4 可以组成1-10(1+2+3+4)以内的任何数x,组成完剩余的就是(10-x)了。同理,可以推广。
所以其实这个w+b就是障眼法,其实只要球的总数够用,就可以满足要求了。
1 | #include <bits/stdc++.h> |
唉,WA了一次,循环n开小了,谁能想到这个109包括比较大的109?6。

我认为这张动图更容易让人理解一点(来自维基百科辗转相除法)
算法的演示动画。最初的绿色矩形的长和宽分别是a=1071,b=462,从中不断铺上462×462的正方形直到剩下部分面积是462 (b) ×147 (a%b) ;然后再铺上147×147的正方形直至剩下21×147的面积;最后,铺上21×21的正方形时,绿色部分就没有了。即21是1071和462的最大公约数。
主要思路和官方题解一致
A[1] 是所有满足 idx%1==0 的 A[idx] 中最大的;(同时保证字典序以及
ai !=gcd(ai,aj) 因为ai是最大的嘛,你aj都没ai大,最大公因数怎么可能等于ai那)
A[2] 是所有满足 idx%2==0 的 A[idx] 中最大的;
同理,剩下可推。
然后上面我们相当于证明了 j % i == 0的情况(此时最大公倍数为 i ),接下来我们看看j % i ≠ 0 的情况

长话短说,就是我们可以把 j % i ≠ 0 的问题转化为 i % g == 0 的问题,然后又回归到原来这个问题上了
基本就是官方题解思路

其实这个有点像埃氏筛(sieve-like),所以最后的时间复杂度也和他很像。
筛法的核心代码长这样
1 | for(int i=1;i<=n;++i){ |
1 | #include <bits/stdc++.h> |
这个比较好,一次提交过,
我们来对想求的进行一下变换

所以就看 y(即m) 里有几个 x^nx 就行了
至于可以被y整除的 x^y ,那个上题中我们证明了这样的情况不会出现在 y ≥ 2**(ceil(log2(x))+1) 之后(**是python中的次方)
然后我们知道^为不进位加法,故 x^nx ≤ (n+1)*x (不进位加法必然不可能比进位加法大嘛),所以我们先看有多少 nx,再通过一些信息,反推出有多少个 x^nx。
然后开开心心码个程序
1 | #include <bits/stdc++.h> |
样例都过不了?
不要慌,这是因为有回退现象。

但是会有一些非常讨厌的回退,比如说上图,如果你只判到6,你会觉得6是一个不行的数,但是实际上6是可以的,其由 1^(1*7)=6 得来,同理,4也是这样。
那回退现象最多会跨多少出现那?其实最多出现在后面一个,因为^他最多把之前加上的给完全抵消掉,他不可能起到比 -x 更强的效果,就像他不会起到比 +x 更强的效果一样。
1 | // 预防思路讲解中遇到的回退现象 |
加了以下这个&& 是因为被2 9这个数据卡了,(x^(m/x+1)*x) ≤ min(xchange,m) ++ans相当于重复了,≤min(xchange,m) 的早就被我们统计过了,不用再统计了。
1 | (x^(m/x+1)*x)>min(xchange,m) |
https://codeforces.com/contest/2039/submission/293249612
1 | #include <bits/stdc++.h> |
暴力程序(确保正确理解题意)
1 | #include <bits/stdc++.h> |
我这个程序老是会多一个,后来发现其实整个思路就有点问题
1 | #include <bits/stdc++.h> |
思路和官方题解应该差不多,但我自认为还是比他讲的清楚一点,其实就是一个对暴力法的上界优化
有一点是肯定的,d<=floor(p/2) d 才可能被 p 整除
当然这题肯定还是和位运算相关嘛,所以我们更关心的其实是 d 的二进制最高位和 p 是不一样的
然后我大概猜到是怎么一回事了。
只需要对暴力代码进行一些小小的改动就行
1 | for(ll y=1;y<=min(m,change(x));++y) { |
把循环上界改成 min(m,change(x)) 就行
那这个 change(x) 是啥那?
1 | inline ll change(ll x) { |
其实很简单,就是 2∗∗(ceil(log2(x))) 的意思(**是次方的意思),只不过写了个循环而已 。
然后我们来说我大概猜到什么了
y 可以很大,相对来说 x 就比较小,那么当 y 很大的时候,d=x^y ( ^是异或的意思) 的高位完全是跟着 y 走的,但这样的 d 首先不可能被 x 整除,其次也不可被y整除(我们前面看了,d 的高位是不能和 y 一样的)
当然这个 y 要多大才会这样那?其实只要大到 y 的最高位异或时不受 x 影响就行了,也就是
y>=2∗∗(ceil(log2(x)))
其实异或还真和加法很像,一个高位的数异或低位的数几乎不会有什么影响。
1 | #include <bits/stdc++.h> |
暴力
1 | #include <bits/stdc++.h> |