博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3542:DZY Loves March
阅读量:5816 次
发布时间:2019-06-18

本文共 4338 字,大约阅读时间需要 14 分钟。

询问是要求

$\sum_{i=1}^n((x[i]-a)^2+(y[i]-b)^2)(x[i]=a||y[i]=b)$

即求

$\sum_{i=1}^n(x[i]-a)^2(y[i]=b)+\sum_{i=1}^n(y[i]-b)^2(x[i]=a)$

拆开得

$\sum_{i=1}^n(x[i]^2-2ax[i]+a^2)(y[i]=b)+\sum_{i=1}^n(y[i]^2-2by[i]+b^2)(x[i]=a)$

所以只要算出编号在区间[l,r]中x[i]=a的所有点的个数、y的和、y的平方和,以及编号在区间[l,r]中y[i]=b的所有点的个数、x的和、x的平方和。

对所有x[i]=a的点建立一棵平衡树,维护区间内y的信息,对所有y[i]=b的点建立一棵平衡树,维护区间内x的信息。

由于$x[i],y[i]\leq10^{18}$,所以不能直接建立2M棵平衡树,于是我就用了map,

rx[i]表示维护x=i的所有点的平衡树的根节点下标,ry[i]表示维护x=i的所有点的平衡树的根节点下标

 

修改:

1.x[i]+=k

在rx[x[i]]树中找到id=i的点,把val置0

x[i]+=k

在rx[x[i]]树中把id=i的点的val修改为y[i]

在ry[y[i]]树中把id=i的点的val修改为x[i](不存在该点则插入)

2.y[i]+=k

在ry[y[i]]树中找到id=i的点,把val置0

y[i]+=k

在ry[y[i]]树中把id=i的点的val修改为x[i]

在rx[x[i]]树中把id=i的点的val修改为y[i](不存在该点则插入)

时间复杂度$O(\log n)$,每次修改最多插入一个新节点

 

查询:

查询编号在区间[l,r]内的x[i]=a或者y[i]=b的军队集结到(a,b)的费用

在rx[a]树中查询区间[l,r]的和s、平方和s2、以及真实存在的节点个数n

$ans+=s2-2bs+nb^2$

在ry[b]树中查询区间[l,r]的和s、平方和s2、以及真实存在的节点个数n

$ans+=s2-2as+na^2$

时间复杂度$O(\log n)$

 

所以总的时间复杂度为$O((n+t)\log n)$,空间复杂度为$O(n+t)$

由于我用了map,以及为了偷懒打了替罪羊树,以及%用的太多,所以常数比较大。

 

 

 

#include
#include
#include
#define N 100010#define M 300010using namespace std;typedef long long ll;const double A=0.6;const ll P=1000000007;inline void read(ll&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10LL)+=c-'0';}int size[M],son[M][2],ex[M],pos[M],f[M],tot;int balance[M];bool real[M],tr[M];ll val[M],sum[M],s2[M],tv[M],tmp;int tp[M],id[M],cnt;ll tsum,ts2,tsize;ll X[N],Y[N],x,y,z,ans;int n,T;char ch;map
rx,ry;inline ll sqr(ll x){return ((x%P)*(x%P))%P;}int ins(int x,int p,ll v){ size[x]++; int b=p>=pos[x]; if(!son[x][b]){ son[x][b]=++tot;f[tot]=x;size[tot]=ex[tot]=real[tot]=1; pos[tot]=p; sum[tot]=val[tot]=v; s2[tot]=sqr(v); return tot; }else return ins(son[x][b],p,v);}void dfs(int x){ if(son[x][0])dfs(son[x][0]); tp[++cnt]=pos[x];tv[cnt]=val[x];tr[cnt]=real[x];id[cnt]=x; if(son[x][1])dfs(son[x][1]);}inline void up(int x){ size[x]=size[son[x][0]]+size[son[x][1]]+1; sum[x]=(sum[son[x][0]]+sum[son[x][1]]+val[x])%P; s2[x]=(s2[son[x][0]]+s2[son[x][1]]+sqr(val[x]))%P; ex[x]=ex[son[x][0]]+ex[son[x][1]]+real[x];}int build(int fa,int l,int r){ int mid=(l+r)>>1,x=id[mid]; f[x]=fa;son[x][0]=son[x][1]=0; pos[x]=tp[mid];val[x]=tv[mid];real[x]=tr[mid]; if(l==r){ size[x]=1; sum[x]=val[x]; s2[x]=sqr(val[x]); ex[x]=real[x]; return x; } if(l
mid)son[x][1]=build(x,mid+1,r); up(x); return x;}inline int rebuild(int x){ cnt=0;dfs(x);return build(f[x],1,cnt);}inline void insert(int&root,int p,int v){ if(!root){ size[root=++tot]=1; balance[tot]=1; ex[tot]=real[tot]=1; pos[tot]=p; sum[tot]=val[tot]=v; s2[tot]=sqr(v); return; } balance[root]++; int x=ins(root,p,v),d=0,z=x; while(f[z])up(z=f[z]),d++; if(d
pos[x]],p);}inline void change(int&root,int p,ll v,bool r){ int x=find(root,p); if(x){ val[x]=v; real[x]=r; while(x)up(x),x=f[x]; return; } insert(root,p,v);}void ask(int x,int a,int b,int c,int d){ if(c<=a&&b<=d){ tsize+=ex[x]; (tsum+=sum[x])%=P; (ts2+=s2[x])%=P; return; } if(c<=pos[x]&&pos[x]<=d){ if(real[x])tsize++; (tsum+=val[x])%=P; (ts2+=sqr(val[x]))%=P; } if(c
pos[x]&&son[x][1])ask(son[x][1],pos[x]+1,b,c,d);}int main(){ scanf("%d",&n);read(tmp); for(int i=1;i<=n;i++){ read(X[i]),read(Y[i]); insert(rx[X[i]],i,Y[i]%P); insert(ry[Y[i]],i,X[i]%P); } scanf("%d",&T); while(T--){ while(!((ch=getchar())=='U'||(ch=='D')||(ch=='L')||(ch=='R')||(ch=='Q'))); if(ch=='U'){//y+ read(x),read(y);x^=ans; change(ry[Y[x]],x,0,0); Y[x]+=y; change(ry[Y[x]],x,X[x]%P,1); change(rx[X[x]],x,Y[x]%P,1); } if(ch=='D'){//y- read(x),read(y);x^=ans; change(ry[Y[x]],x,0,0); Y[x]-=y; change(ry[Y[x]],x,X[x]%P,1); change(rx[X[x]],x,Y[x]%P,1); } if(ch=='L'){//x- read(x),read(y);x^=ans; change(rx[X[x]],x,0,0); X[x]-=y; change(rx[X[x]],x,Y[x]%P,1); change(ry[Y[x]],x,X[x]%P,1); } if(ch=='R'){//x+ read(x),read(y);x^=ans; change(rx[X[x]],x,0,0); X[x]+=y; change(rx[X[x]],x,Y[x]%P,1); change(ry[Y[x]],x,X[x]%P,1); } if(ch=='Q'){ read(x),read(y),read(z);x^=ans; tsize=tsum=ts2=ans=0; ask(rx[X[x]],1,n,y,z); (ans+=(ts2-((2LL*(Y[x]%P))%P*tsum)%P+(tsize*sqr(Y[x]))%P))%=P; while(ans<0)ans+=P; tsize=tsum=ts2=0; ask(ry[Y[x]],1,n,y,z); (ans+=(ts2-((2LL*(X[x]%P))%P*tsum)%P+(tsize*sqr(X[x]))%P))%=P; while(ans<0)ans+=P; printf("%lld\n",ans); } } return 0;}

 

转载地址:http://olmbx.baihongyu.com/

你可能感兴趣的文章
6、Web Service-拦截器
查看>>
Flask 源码流程,上下文管理
查看>>
stream classdesc serialVersionUID = -7218828885279815404, local class serialVersionUID = 1.
查看>>
ffmpeg相关资源
查看>>
ZAB与Paxos算法的联系与区别
查看>>
java 读取本地的json文件
查看>>
Breaking parallel loops in .NET C# using the Stop method z
查看>>
Android Content Provider Guides
查看>>
修改故障转移群集心跳时间
查看>>
[轉]redis;mongodb;memcache三者的性能比較
查看>>
微软职位内部推荐-Sr DEV
查看>>
用计算器计算“异或CRC”
查看>>
LINK:fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 (转)
查看>>
让你的WPF程序在Win7下呈现Win8风格主题
查看>>
深刻理解C#的传值调用和传引用调用
查看>>
Windows环境配置Apache+Mysql+PHP
查看>>
JDBC二查询(web基础学习笔记八)
查看>>
监听器(web基础学习笔记二十二)
查看>>
802.11 学习笔记
查看>>
Leetcode-Database-176-Second Highest Salary-Easy(转)
查看>>