给定序列
挺好的一道水题,有一道类似的题,AcWing 246 区间最大公约数,简而言之就是实现区间加,区间求
首先有一个性质,更相减损术,即
然后不难发现可以通过更相减损术,对这个矩形横向进行差分:
发现除了最初始的位置,剩下的每一列都是相同的,所以我们不难想到,除了第一行第一列之外的数,会因为重复所以可以不用考虑。同时对于对应的第一列,也可以差分。最后就可以变成,对于一段查询,求的是序列
然后考虑如何快速维护区间的
xxxxxxxxxx
811
2
3
4
5
6
7
8
9
10
11using namespace std;
12
13mt19937 rnd(random_device{}());
14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
15bool rnddd(int x){return rndd(1, 100) <= x;}
16
17typedef unsigned int uint;
18typedef unsigned long long unll;
19typedef long long ll;
20typedef long double ld;
21
22
23
24template < typename T = int >
25inline T read(void);
26
27int N, Q;
28int A[MAXN], B[MAXN], dA[MAXN], dB[MAXN];
29
30class SegTree{
31private:
32 int tr[MAXN << 2];
33
34
35
36public:
37 void Pushup(int p){tr[p] = __gcd(tr[LS], tr[RS]);}
38 void Build(bool flag, int p = 1, int gl = 1, int gr = N){//true - line(y), false - row(x)
39 if(gl == gr)return tr[p] = flag ? dB[gl] : dA[gl], void();
40 Build(flag, LS, gl, MID), Build(flag, RS, MID + 1, gr);
41 Pushup(p);
42 }
43 int Query(int l, int r, int p = 1, int gl = 1, int gr = N){
44 if(l <= gl && gr <= r)return tr[p];
45 if(r <= MID)return Query(l, r, LS, gl, MID);
46 if(l >= MID + 1)return Query(l, r, RS, MID + 1, gr);
47 return __gcd(Query(l, r, LS, gl, MID), Query(l, r, RS, MID + 1, gr));
48 }
49}stLine, stRow;
50
51int main(){
52 N = read(), Q = read();
53 for(int i = 1; i <= N; ++i)A[i] = read(), dA[i] = A[i] - A[i - 1];
54 for(int i = 1; i <= N; ++i)B[i] = read(), dB[i] = B[i] - B[i - 1];
55 stLine.Build(true), stRow.Build(false);
56 while(Q--){
57 int h1 = read(), h2 = read(), w1 = read(), w2 = read();
58 int ans = A[h1] + B[w1];
59 if(w1 != w2)ans = __gcd(ans, stLine.Query(w1 + 1, w2));
60 if(h1 != h2)ans = __gcd(ans, stRow.Query(h1 + 1, h2));
61 printf("%d\n", abs(ans));
62 }
63 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
64 return 0;
65}
66
67template < typename T >
68inline T read(void){
69 T ret(0);
70 int flag(1);
71 char c = getchar();
72 while(c != '-' && !isdigit(c))c = getchar();
73 if(c == '-')flag = -1, c = getchar();
74 while(isdigit(c)){
75 ret *= 10;
76 ret += int(c - '0');
77 c = getchar();
78 }
79 ret *= flag;
80 return ret;
81}
update-2022_12_06 初稿