Rectangle GCD
题目
(好吧,结论很好猜,但数学太烂,不敢相信自己的证明,怎么想都很奇怪。
当作结论积累
\[gcd(a_1,a_2,...,a_i,...,a_k,...,a_n)=gcd(a_1,a_2,...,a_i,...,a_k-a_i,...a_n)
\]
证明:肯定是假设 \(gcd=d\) 然后通过整除性质推导。(私以为证明 “操作后 \(gcd\) 不会变大 ” 用反证法很好证)。
理解记忆:更相减损可扩展至 \(n\) 个数的 \(gcd\),任意加减都不影响结果。
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';c=getchar();
}
return x*f;
}
inline int gcd(int x,int y){
if(y==0)return x;
return gcd(y,x%y);
}
#define N 200005
int T=19,e[20],lo[N];
void init(){
e[0]=1;
for(int i=1;i<=T;++i)e[i]=e[i-1]<<1;
lo[1]=0;
for(int i=2;i<N;++i)lo[i]=lo[i>>1]+1;
}
struct node{
int a[N],st[N][20];
void init(int n){
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=n;++i)st[i][0]=abs(a[i]-a[i-1]);
for(int len=1;len<=T;++len){
for(int i=1;i<=n-e[len]+1;++i){
st[i][len]=gcd(st[i][len-1],st[i+e[len-1]][len-1]);
}
}
}
int get(int l,int r){
if(l>r)return 0;
int len=lo[r-l+1];
return gcd(st[l][len],st[r-e[len]+1][len]);
}
}A[2];
int main(){
int n=read(),q=read();
init();
A[0].init(n);A[1].init(n);
while(q--){
int h1=read(),h2=read(),w1=read(),w2=read(),ans=0;
ans=gcd(ans,A[0].get(h1+1,h2));
ans=gcd(ans,A[1].get(w1+1,w2));
ans=gcd(ans,A[0].a[h1]+A[1].a[w1]);
cout<<abs(ans)<<endl;
}
return 0;
}
浙公网安备 33010602011771号