标签:进制 str class struct 区间 fine math void type
??给定一个长度为\(n\)的序列\(a_1, a_2, \dots , a_n\)(\(1 \leq n, a_i \leq 5 \times 10^5\))求有多少对$(i, j) $满足\(1 \leq i \leq j \leq n\)且\(\gcd (a_i, a_{i + 1}, \dots , a_j) \oplus (a_i \lor a_{i + 1} \lor \dots \lor a_j) = k\)。
?
??容易想到,当\(i\)不变时,随着\(j\)从小变大,区间\(\gcd\)的值只会变小,且因为每次都要除以一个质因子,所以最多变小\(log\)次就到\(1\),同时区间或的值只会变大,且因为每次都会有一个二进制位变化,所以最多变大\(log\)次就到最大值。
??如果我们当前知道对于每个\(i\),所有可能出现的区间\(\gcd\)和区间或的值,就能求出\((i,j)\)的对数。
??同时,我们也可以由\(i + 1\)得到\(i\)可能出现的区间\(\gcd\)和区间或的值,所以我们可以从\(n\)开始枚举到\(1\),直接求解即可。
#include <iostream>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define MAX_N (500000 + 5)
#define SIZE (1 << 21)
#define Getchar() (p1 == p2 && (p2 = (p1 = fr) + fread(fr, 1, SIZE, stdin), p1 == p2) ? EOF : *p1++)
using namespace std;
char fr[SIZE], * p1 = fr, * p2 = fr;
void Read(int & res)
{
res = 0;
char ch = Getchar();
while(!isdigit(ch)) ch = Getchar();
while(isdigit(ch)) res = res * 10 + ch - '0', ch = Getchar();
return;
}
struct Interval
{
int val;
int r;
};
int n, k;
int a[MAX_N];
Interval g1[25], g2[25];
int tot1, tot2;
long long ans;
int gcd(int a, int b)
{
int c;
while(b)
{
c = a % b;
a = b;
b = c;
}
return a;
}
void Update(int x, Interval g[], int & tot)
{
g[tot + 1].val = 0x7f7f7f7f;
int d = 0;
for(int i = 1; i + d <= tot; ++i)
{
g[i] = g[i + d];
while(g[i + d].val == g[i + d + 1].val)
{
g[i] = g[i + d + 1];
++d;
}
}
tot -= d;
return;
}
int main()
{
Read(n); Read(k);
for(int i = 1; i <= n; ++i)
{
Read(a[i]);
}
int t1, t2;
g1[0].r = g2[0].r = n + 1;
for(int i = n; i; --i)
{
for(int j = 1; j <= tot1; ++j)
{
g1[j].val = gcd(g1[j].val, a[i]);
}
for(int j = 1; j <= tot2; ++j)
{
g2[j].val |= a[i];
}
g1[++tot1] = g2[++tot2] = (Interval){a[i], i};
Update(i, g1, tot1);
Update(i, g2, tot2);
t1 = tot1;
t2 = tot2;
while(t1 && t2)
{
if((g1[t1].val ^ g2[t2].val) == k)
{
ans += min(g1[t1 - 1].r, g2[t2 - 1].r) - max(g1[t1].r, g2[t2].r);
}
if(g1[t1 - 1].r <= g2[t2 - 1].r) --t1;
else --t2;
}
}
printf("%lld", ans);
return 0;
}
标签:进制 str class struct 区间 fine math void type
原文地址:https://www.cnblogs.com/kcn999/p/11355193.html