天才绅士少女助手克里斯蒂娜 [数学+树状数组]
然后处理前缀和, 时间复杂度 .
接着上式化简得
使用树状数组维护即可 .
#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\n", ( (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;
}