题目大意:给你两个数x,y
cnt = 0
while (gcd(x, y) == 1) x++, y++, cnt++;
求cnt的结果
gcd性质:gcd(x, y) == gcd(x, y - x)
则gcd(x + k, y + k) == gcd(x + k, y - x) == 1。
枚举y-x的素因子p,找出满足(x + k) % p == 0的k的最小值。
(x + k) % p == 0 ——> k = p - x % p 。
const int N = 1e7 + 5;
int mp[N];
vector primes;
void init() { //求出最小质因子
for (int i = 2; i <= N; i++) {
if (!mp[i]) {
mp[i] = i;
primes.push_back(i);
}
for (auto p : primes) {
if (i * p > N) break;
mp[i * p] = p;
if (i % p == 0) break;
}
}
}
void solve() {
int x, y;
cin >> x >> y;
if(y - x == 1) {
cout << -1 << "\n";
return;
}
if(__gcd(x, y) != 1) {
cout << 0 << "\n";
return;
}
int now = y - x;
int ans = 1e9;
while(now > 1) {
int tmp = mp[now];
ans = min(ans, tmp - x % tmp); //答案取最小值
now /= tmp; //质因数分解
}
cout << ans << "\n";
}
题目大意:给你一个长度为n的数组a(2<=n<=2e5,1<=a[i]<=n),
求有多少个i,j(i<=j)满足a[i]^a[i+1]...^a[j]的因子数为偶数。
从反面出发,求子数组异或和为奇数的个数,用总数减去即使答案。
思考:什么样的数因子数为奇数个? 完全平方数。
异或前缀和,在当前位置判断它前面有多少个数与它异或的值为完全平方数。
做法:枚举2n以内的所有完全平方数(子数组的最大异或和不会超过2n),统计前面出现过的异或前缀和的个数,
用总数减去满足条件的个数。
void solve() {
int n;
cin >> n;
ll ans = 1LL * n * (n + 1) / 2;
vector cnt(2 * n);
int cur = 0;
cnt[cur]++;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
cur ^= a;
for (int j = 0; j * j < 2 * n; j++) {
if((cur ^ (j * j)) < 2 * n) {
ans -= cnt[cur ^ (j * j)];
}
}
cnt[cur]++;
}
cout << ans << "\n";
}
题目大意:
给你n-1个整数:a1,a2...a[n-1]。
你的任务是构造一个长度为n的数组b,满足一下条件:
0~n-1都在b中恰好出现一次,a[i] = b[i] ^ b[i + 1](1<=i<=n-1)。
看到异或这种直接算的不好算的东西,首先很自然的就要往拆位,按照每一位考虑方向想一想。
由a[i]=b[i]^b[i+1]简单推导一下:
a[1]=b[1]^b[2]
a[1]^a[2]=b[1]^b[3]
a[1]^a[2]^a[3]=b[1]^b[4]
...
可以看出b[i]=b[1]^(a[i - 1]^...^a[1])
所以我们只需要求出b[1]
求b[1]:先把a数组异或前缀和一下,统计0~n-1与a[1]~a[n-1]之间每一位中1的个数,若不相等则b[1]该位为1。
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector a(n - 1);
for (int i = 0; i < n - 1; i++) {
cin >> a[i];
}
for (int i = 1; i < n - 1; i++) {
a[i] ^= a[i - 1];
}
int b1 = 0;
for (int i = 0; i < 20; i++) {
int cnt1[2]{}, cnt2[2]{};
for (int j = 0; j < n; j++) {
cnt1[j >> i & 1]++;
}
for (int j = 0; j < n - 1; j++) {
cnt2[a[j] >> i & 1]++;
}
if(cnt1[1] != cnt2[1]) {
b1 |= 1 << i;
}
}
cout << b1 << ' ';
for (int i = 0; i < n - 1; i++) {
cout << (a[i] ^ b1) << " \n"[i == n - 2];
}
return 0;
}