题解
vi
是一个向量,
那么需要求的就是叉积的平方和。
假设
v1=(x1,y1),v2=(x2,y2)
那么
v1∗v2=x1∗y2−x2∗y1
可以发现对于一段区间l,r的叉积平方和,
就是
∑x2i∗∑y2i−(∑xiyi)2
那么最后的答案就与
x2i,y2i,xiyi
这里维护区间和,可以用线段树,树状数组。
code
#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#define ll long long
#define N 1000003
#define db double
#define P putchar
#define G getchar
#define mo 20170927
using namespace std;
char ch;
void read(ll &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
void writeln(ll x){write(x);P('\n');}
struct node
{
ll x,y;
}a[N];
ll n,m,t,x,l,r;
ll ans,f[3][N];
int x_(int x){return x&(-x);}
void ins(int x,ll y,int z)
{
y=(y%mo+mo)%mo;
for(int i=x;i<=n;i=i+x_(i))
f[z][i]=(f[z][i]+y)%mo;
}
ll get(int x,int y)
{
ll s=0;
for(int i=x;i;i=i-x_(i))
s=(s+f[y][i])%mo;
return s;
}
ll fi(int l,int r,int z)
{
return (get(r,z)-get(l-1,z)+mo)%mo;
}
void put(int x)
{
ins(x,sqr(a[x].x)%mo,0);
ins(x,sqr(a[x].y)%mo,1);
ins(x,a[x].x*a[x].y%mo,2);
}
void del(int x)
{
ins(x,-sqr(a[x].x)%mo,0);
ins(x,-sqr(a[x].y)%mo,1);
ins(x,-a[x].x*a[x].y%mo,2);
}
int main()
{
freopen("kurisu.in","r",stdin);
freopen("kurisu.out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;i++)
read(a[i].x),read(a[i].y),put(i);
for(int i=1;i<=m;i++)
{
read(t);
if(t==1)read(x),del(x),read(a[x].x),read(a[x].y),put(x);
else
{
read(l);read(r);
ans=fi(l,r,0)*fi(l,r,1)%mo-sqr(fi(l,r,2))%mo;
ans=(ans+mo)%mo;
writeln(ans);
}
}
}