【google】 google

Google mock view

前段时间做了一下googlemock interview,其中有道题目印象深刻。

1. 区间查询

题目

给定长度为n的数组A,给定组数$[i,j]$,求以下结果:

所求结果对$10^{9} + 7$取模, 其中满足以下:

  1. 首先看到类似的求区间的数列我们首先想到的就是用线段树。我们首先用数学分解的方法来将公式进行分解和变换:由上述变换我们就可以知道如何通过线段树对其进行分解,我们设线段树的每个非叶子节点,包含的范围为$(i,j)$,且包含两个值:有了上述变换以后我们可以知道线段树的变化,假如本次我们需要查询的区间为$(i,j)$,假设线段从$mid$处断开分为两个子节点,则我们可以知道如下的求和公式:而$val$可以变换如下:根据以上变换,我们则可以轻易的用线段树可以在$lg(n)$的时间复杂度内求出所有的查询。

    代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    #include<bits/stdc++.h>

    using namespace std;

    typedef long long ll;
    typedef pair<int,int> pii;
    long long MOD = 1e9 + 7;
    const long long MAXN = 2000000;
    struct segTreeNode{
    long long val;
    long long prod;
    int l;
    int r;
    };

    #define CHL(x) (x*2)
    #define CHR(x) (x*2+1)
    segTreeNode tree[MAXN];

    long long fastpow(long long x,long long y,long long mod){
    long long ret = 1;
    for(int i = y; i != 0; i >>= 1){
    if(i&1) ret = (ret*x)%mod;
    x = (x*x)%mod;
    }
    return ret;
    }

    bool pushUpTree(int idx){
    int mid = (tree[idx].l + tree[idx].r)>>1;
    int d = mid - tree[idx].l + 1;
    long long pl = tree[CHL(idx)].prod;
    long long pr = tree[CHR(idx)].prod;
    tree[idx].prod = pl*pr%MOD;
    tree[idx].val = tree[CHL(idx)].val*tree[CHR(idx)].val*fastpow(pr,d,MOD)%MOD;
    return true;
    }

    bool buildTree(int l,int r,vector<int> & arr,int idx){
    if(l > r) return false;
    tree[idx].l = l;
    tree[idx].r = r;
    tree[idx].val = 1;
    tree[idx].prod = 1;
    if(l == r){
    tree[idx].val = arr[l];
    tree[idx].prod = arr[l];
    return true;
    }

    int mid = (l+r)>>1;
    buildTree(l,mid,arr,CHL(idx));
    buildTree(mid+1,r,arr,CHR(idx));
    pushUpTree(idx);
    return true;
    }

    long long queryTree(int l,int r,int idx){
    if(tree[idx].r < l || tree[idx].l > r) return 1;
    if(l <= tree[idx].l && tree[idx].r <= r){
    long long d = tree[idx].l - l;
    return tree[idx].val*fastpow(tree[idx].prod,d,MOD)%MOD;
    }

    int mid = (tree[idx].l + tree[idx].r)>>1;
    if(l > mid){
    return queryTree(l,r,CHR(idx));
    }else if(r <= mid){
    return queryTree(l,r,CHL(idx));
    }else{
    long long lval = queryTree(l,r,CHL(idx));
    long long rval = queryTree(l,r,CHR(idx));
    return lval*rval%MOD;
    }
    }

    int main(){
    int n;
    int t;
    int l,r;
    memset(tree,0,sizeof(tree));
    cin>>n;
    vector<int> arr = vector<int>(n);
    for(int i = 0; i < n; ++i) cin>>arr[i];
    buildTree(0,n-1,arr,1);
    cin>>t;
    for(int i = 0; i < t; ++i){
    cin>>l>>r;
    l--;
    r--;
    cout<<queryTree(l,r,1)<<endl;
    }
    return 0;
    }

#

欢迎关注和打赏,感谢支持!


【google】 google
http://example.com/2026/09/08/力扣周赛题解/71/
Author
Mike Meng
Posted on
September 8, 2026
Licensed under