zoukankan      html  css  js  c++  java
  • 天才绅士少女助手克里斯蒂娜 [数学+树状数组]

    天才绅士少女助手克里斯蒂娜


    color{blue}{最初想法}

        i=lrj=i+1r(xiyjxjyi)2=i=lrxi2j=i+1ryj2+i=lryi2j=i+1rxj22i=lrxiyij=i+1rxjyjegin{aligned}& sum_{i=l}^{r}sum_{j=i+1}^r(x_iy_j-x_jy_i)^2 \ &= sum_{i=l}^rx_i^2sum_{j=i+1}^ry_j^2 + sum_{i=l}^ry_i^2sum_{j=i+1}^rx_j^2-2sum_{i=l}^rx_iy_isum_{j=i+1}^rx_jy_j\ end{aligned}

    然后处理前缀和, 时间复杂度 O(N2)O(N^2) .


    color{red}{正解部分}

    接着上式化简得

        i=lrxi2j=i+1ryj2+i=lryi2j=i+1rxj22i=lrxiyij=i+1rxjyj=i=lrxi2j=i+1ryj2+i=lrxi2j=li1yj2(i=lrxiyij=lrxjyji=lrxi2yi2)=i=lrxi2(j=lryj2yi2)i=lrxiyij=lrxjyj+i=lrxi2yi2=i=lrxi2j=lryj2i=lrxi2yi2i=lrxiyij=lrxjyj+i=lrxi2yi2=i=lrxi2j=lryj2i=lrxiyij=lrxjyjegin{aligned} & sum_{i=l}^rx_i^2sum_{j=i+1}^ry_j^2 + sum_{i=l}^ry_i^2sum_{j=i+1}^rx_j^2-2sum_{i=l}^rx_iy_isum_{j=i+1}^rx_jy_j\ &= sum_{i=l}^rx_i^2sum_{j=i+1}^ry_j^2 + sum_{i=l}^rx_i^2sum_{j=l}^{i-1}y_j^2 - (sum_{i=l}^rx_iy_isum_{j=l}^rx_jy_j - sum_{i=l}^r x_i^2y_i^2)\ &= sum_{i=l}^rx_i^2(sum_{j=l}^ry_j^2 - y_i^2) - sum_{i=l}^rx_iy_isum_{j=l}^rx_jy_j + sum_{i=l}^r x_i^2y_i^2\ &= sum_{i=l}^rx_i^2sum_{j=l}^ry_j^2 - sum_{i=l}^rx_i^2y_i^2 - sum_{i=l}^rx_iy_isum_{j=l}^rx_jy_j + sum_{i=l}^r x_i^2y_i^2 \ &= sum_{i=l}^rx_i^2sum_{j=l}^ry_j^2 - sum_{i=l}^rx_iy_isum_{j=l}^rx_jy_j end{aligned}


    color{red}{实现部分}

    使用树状数组维护即可 .

    #include<bits/stdc++.h>
    #define reg register
    typedef long long ll;
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 1000005;
    const int mod = 20170927;
    
    int N;
    int M;
    
    ll v[maxn][2];
    
    struct Bit_Tree{
            ll v[maxn];
            void Add(int k, ll p){ p%=mod; while(k<=N)v[k]+=p,k+=k&-k; }
            ll Query(int k){ ll s = 0; while(k)s+=v[k],s%=mod,k-=k&-k; return s; }
    } bit_t[3];
    
    void Work(){
            int opt = read();
            if(opt == 1){
                    int pos = read();
                    bit_t[0].Add(pos, -v[pos][0]*v[pos][0]);
                    bit_t[1].Add(pos, -v[pos][1]*v[pos][1]);
                    bit_t[2].Add(pos, -v[pos][0]*v[pos][1]);
                    v[pos][0] = read(), v[pos][1] = read();
                    bit_t[0].Add(pos, v[pos][0]*v[pos][0]);
                    bit_t[1].Add(pos, v[pos][1]*v[pos][1]);
                    bit_t[2].Add(pos, v[pos][0]*v[pos][1]);
            }else{
                    int l = read(), r = read();
                    ll Tmp_1 = bit_t[0].Query(r) - bit_t[0].Query(l-1);
                    ll Tmp_2 = bit_t[1].Query(r) - bit_t[1].Query(l-1);
                    ll Tmp_3 = bit_t[2].Query(r) - bit_t[2].Query(l-1);
                    Tmp_1 = (Tmp_1 % mod + mod) % mod;
                    Tmp_2 = (Tmp_2 % mod + mod) % mod;
                    Tmp_3 = (Tmp_3 % mod + mod) % mod;
                    printf("%lld
    ", ( (Tmp_1*Tmp_2%mod) - (Tmp_3*Tmp_3%mod) + mod ) % mod);
            }
    }
    
    int main(){
            N = read(), M = read();
            for(reg int i = 1; i <= N; i ++) v[i][0] = read(), v[i][1] = read(); 
            for(reg int i = 1; i <= N; i ++){
                    bit_t[0].Add(i, v[i][0]*v[i][0]);
                    bit_t[1].Add(i, v[i][1]*v[i][1]);
                    bit_t[2].Add(i, v[i][0]*v[i][1]);
            }
            while(M --) Work();
            return 0;
    }
    
  • 相关阅读:
    实验四
    密码破解技术
    222
    111
    6
    5
    4
    第三次
    第二次
    第一次
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822513.html
Copyright © 2011-2022 走看看