Description
Solution
首先我们把整个式子化简一下:
K
=
(
∑
i
=
1
m
(
x
i
−
p
)
2
)
∗
m
K=(\sum^{m}_{i=1}(x_{i}-p)^2)*m
K=(∑i=1m(xi−p)2)∗m
把
(
x
i
−
p
)
2
(x_{i}-p)^2
(xi−p)2拆开,可以得到
K
=
(
∑
i
=
1
m
(
x
i
2
−
x
i
∗
p
−
x
i
∗
p
+
p
2
)
)
∗
m
K=(\sum^{m}_{i=1}(x_{i}^2-x_{i}*p-x_{i}*p+p^2))*m
K=(∑i=1m(xi2−xi∗p−xi∗p+p2))∗m
也就是
K
=
(
∑
i
=
1
m
(
x
i
2
−
2
∗
x
i
∗
p
+
p
2
)
)
∗
m
K=(\sum^{m}_{i=1}(x_{i}^2-2*x_{i}*p+p^2))*m
K=(∑i=1m(xi2−2∗xi∗p+p2))∗m
再把sigama拆开,就可以得到
K
=
(
∑
i
=
1
m
x
i
2
)
∗
m
−
2
∗
(
∑
i
=
1
m
x
i
)
∗
p
∗
m
+
p
2
∗
m
2
K=(\sum^{m}_{i=1}x_{i}^2)*m-2*(\sum^{m}_{i=1}x_{i})*p*m+p^2*m^2
K=(∑i=1mxi2)∗m−2∗(∑i=1mxi)∗p∗m+p2∗m2
令
A
=
∑
i
=
1
m
x
i
2
A=\sum^{m}_{i=1}x_{i}^2
A=∑i=1mxi2,
B
=
∑
i
=
1
m
x
i
B=\sum^{m}_{i=1}x_{i}
B=∑i=1mxi
那么整个式子就变成了
K
=
A
m
−
2
∗
B
∗
p
∗
m
+
p
2
∗
m
2
K=Am-2*B*p*m+p^2*m^2
K=Am−2∗B∗p∗m+p2∗m2
又知道
p
=
∑
i
=
1
m
x
i
m
p=\frac{\sum^{m}_{i=1}x_{i}}{m}
p=m∑i=1mxi,即
p
=
B
m
p=\frac{B}{m}
p=mB
再把这个式子带入,得
K
=
A
m
−
2
B
B
m
∗
m
+
(
B
m
)
2
∗
m
2
K=Am-2B\frac{B}{m}*m+(\frac{B}{m})^2*m^2
K=Am−2BmB∗m+(mB)2∗m2
再化简,得
K
=
A
m
−
2
B
2
m
∗
m
+
B
2
m
2
∗
m
2
K=Am-2\frac{B^2}{m}*m+\frac{B^2}{m^2}*m^2
K=Am−2mB2∗m+m2B2∗m2
K
=
A
m
−
2
B
2
+
B
2
K=Am-2B^2+B^2
K=Am−2B2+B2
即
K
=
A
m
−
B
2
K=Am-B^2
K=Am−B2
可以考虑离线的做法。
首先把所有元素按照
w
i
w_{i}
wi排序,所有询问按照
z
z
z排序。
这样我们就可以枚举询问,然后把
w
i
w_{i}
wi小于等于
z
z
z的元素全部插入进一个树状数组里。由于上面已经把式子化简了,所以呢我们就可以只记录
A
A
A、
B
B
B和
m
m
m,不需要算出
p
p
p,再区间查询即可。
Code
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int N=4e5+5;
int n,m,q0=1,q1=1;
ll ans[N],c[N][3];
struct node {int w,num;ll pos;}a[N];
struct rec {int x,y,z,num;}q[N];
bool cmp(node x,node y) {return x.w<y.w;}
bool cmp1(rec x,rec y) {return x.z<y.z;}
ll lowbit(int x) {return x&-x;}
void update(int x,ll val) {
while(x<=n) {
c[x][0]+=val;
c[x][1]+=val*val;
c[x][2]++;
x+=lowbit(x);
}
}
ll query(int x,int y) {
ll A=0,cnt=0,B=0;
while(x>0) {
A+=c[x][0];
B+=c[x][1];
cnt+=c[x][2];
x-=lowbit(x);
}
while(y>0) {
A-=c[y][0];
B-=c[y][1];
cnt-=c[y][2];
y-=lowbit(y);
}
if(!cnt)return -1;
return B*cnt-A*A;
}
int main() {
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
scanf("%d%lld",&a[i].w,&a[i].pos);
a[i].num=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=m;i++) {
scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
q[i].num=i;
}
sort(q+1,q+1+m,cmp1);
while(q1<=m) {
while(q0<=n&&a[q0].w<=q[q1].z) {
update(a[q0].num,a[q0].pos);
q0++;
}
ans[q[q1].num]=query(q[q1].y,q[q1].x-1);
q1++;
}
for(int i=1;i<=m;i++)
if(ans[i]==-1)puts("empty");
else printf("%lld\n",ans[i]);
fclose(stdin);
fclose(stdout);
return 0;
}