AtCoder Beginner Contest 254 F (线段树求区间gcd)

https://atcoder.jp/contests/abc254/tasks/abc254_f
题意: 查询子矩阵的所有元素的gcd
思路:
首先要知道gcd的一个性质:
image
那么求h1w1,h2w2的矩阵gcd就等价 gcd( a[h1] + b[w1], gcd[ a[h1 + 1], a[h2]], gcd[ b[w1 + 1], b[w2]])
然后粘一个线段树求gcd板子

#include<bits/stdc++.h>
//#include <bits/extc++.h>
using namespace std;
// using namespace __gnu_cxx;
// using namespace __gnu_pbds;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);  
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
#define ull unsigned long long
#define li __int128_t
#define PII pair<int, int>
#define re register
//#define int long long
const int N = 2e5 + 5;
const int M = 1e6 + 5;
const int mod = 1e9 + 7;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
ll a[N], b[N], ca[N], cb[N];
struct SegTree{
    ll g;
}tra[N<<2], trb[N<<2];
ll gcd(ll a,ll b){
    if(a<0) a=-a; if(b<0) b=-b;
    return b?gcd(b,a%b):a;
}

void push_up(int rt, SegTree *tree){
    tree[rt].g = gcd(tree[rt<<1].g,tree[rt<<1|1].g);
}
void tree_build(int l ,int r,int rt,ll *a, SegTree *tree){

    if(l==r){tree[rt].g=a[l] ;return ;}
    int mid = l+r>>1;
    tree_build(l,mid,rt<<1, a, tree);
    tree_build(mid+1,r,rt<<1|1, a, tree);
    push_up(rt, tree);
}

ll query(int a,int b,int l ,int r,int rt, SegTree *tree)
{
    if(l>b||r<a)return 0;
    if(l>=a&&r<=b)
    return tree[rt].g;
    int mid=l+r>>1;
    return gcd(query(a,b,l,mid,rt<<1, tree),query(a,b,mid+1,r,rt<<1|1, tree));
}
int main() {
  IOS
  int n, q;
  cin >> n >> q;
  for ( int i = 1; i <= n; ++ i ) cin >> a[i], ca[i] = a[i] - a[i - 1];
  for ( int i = 1; i <= n; ++ i ) cin >> b[i], cb[i] = b[i] - b[i - 1];

  tree_build(1,n,1,ca, tra); tree_build(1,n,1,cb,trb);
  while( q -- ) {
    int h1, h2, w1, w2; cin >> h1 >> h2 >> w1 >> w2;
    ll ans = a[h1] + b[w1];
    if( h1 + 1 <= h2 ) ans = gcd( ans, query(h1+1,h2,1,n,1, tra) );
    if( w1 + 1 <= w2 ) ans = gcd( ans, query(w1+1,w2,1,n,1, trb) );
    cout << ans << "\n";
  }

  return 0;
}
posted @ 2022-06-05 10:04  qingyanng  阅读(30)  评论(0编辑  收藏  举报