SDOI2017Day2T3 相关分析
来源:互联网 发布:常见的网络协议有哪些 编辑:程序博客网 时间:2024/06/05 18:04
传送门
题解
首先化式子:
查询:
所以我们只需要在线段树中维护
维护:
操作2:
操作3:
其中
注意:
预处理的时候要注意直接强转为double,因为
运算时不要保留int或long long,直接用double储存,不然会出错(我也不知道为什么);
由于有两种不同的操作,所以必然导致打标记时要出现特判:如果需要对某个位置打增加标记,并且当前点有覆盖标记,那么直接将增加标记加到覆盖标记上;
如果给某个位置打覆盖标记,当前位置的增加标记清零
还有:
pushdown的时候也要注意特判!pushdown的时候也要注意特判!pushdown的时候也要注意特判!
CODE:
#include<cstdio>const int N=1e5+10;const double INF=1e9;struct tree{ double x,y,xy,x2,s1,t1,s2,t2;}t[N<<2],ans;double X[N],Y[N],a[N],b[N];int n,m,L,R,x,y,z;inline void Add2(int l,int r,int now,double S,double T){ t[now].x=(r-l+1)*S+a[r]-a[l-1]; t[now].y=(r-l+1)*T+a[r]-a[l-1]; t[now].xy=(r-l+1)*S*T+(S+T)*(a[r]-a[l-1])+b[r]-b[l-1]; t[now].x2=(r-l+1)*S*S+2*S*(a[r]-a[l-1])+b[r]-b[l-1]; t[now].s1=t[now].t1=0; t[now].s2=S;t[now].t2=T;}inline void Add1(int l,int r,int now,double S,double T){ if(t[now].s2!=INF||t[now].t2!=INF) return Add2(l,r,now,t[now].s2+S,t[now].t2+T);//一定要注意写在里面 t[now].xy+=T*t[now].x+S*t[now].y+(r-l+1)*S*T; t[now].x2+=2*S*t[now].x+(r-l+1)*S*S; t[now].x+=(r-l+1)*S; t[now].y+=(r-l+1)*T; t[now].s1+=S;t[now].t1+=T;}inline void pushdown(int l,int r,int now){ if(t[now].s1||t[now].t1) { int mid=(l+r)>>1; Add1(l,mid,now<<1,t[now].s1,t[now].t1); Add1(mid+1,r,now<<1|1,t[now].s1,t[now].t1); t[now].s1=t[now].t1=0; } if(t[now].s2!=INF||t[now].t2!=INF) { int mid=(l+r)>>1; Add2(l,mid,now<<1,t[now].s2,t[now].t2); Add2(mid+1,r,now<<1|1,t[now].s2,t[now].t2); t[now].s2=t[now].t2=INF; }}inline void update(int now){ int s1=now<<1,s2=now<<1|1; t[now].x=t[s1].x+t[s2].x; t[now].y=t[s1].y+t[s2].y; t[now].xy=t[s1].xy+t[s2].xy; t[now].x2=t[s1].x2+t[s2].x2;}void build(int l,int r,int now){ t[now].s2=t[now].t2=INF; if(l==r) { t[now].x=X[l];t[now].y=Y[l]; t[now].xy=X[l]*Y[l];t[now].x2=X[l]*X[l]; return; } int mid=(l+r)>>1; build(l,mid,now<<1); build(mid+1,r,now<<1|1); update(now);}void add1(int L,int R,int l,int r,int now,double S,double T){ if(L<=l&&r<=R) return Add1(l,r,now,S,T); int mid=(l+r)>>1; pushdown(l,r,now); if(L<=mid) add1(L,R,l,mid,now<<1,S,T); if(R>mid) add1(L,R,mid+1,r,now<<1|1,S,T); update(now);}void add2(int L,int R,int l,int r,int now,double S,double T){ if(L<=l&&r<=R) return Add2(l,r,now,S,T); int mid=(l+r)>>1; pushdown(l,r,now); if(L<=mid) add2(L,R,l,mid,now<<1,S,T); if(R>mid) add2(L,R,mid+1,r,now<<1|1,S,T); update(now);}void ask(int L,int R,int l,int r,int now){ if(L<=l&&r<=R) { ans.x+=t[now].x;ans.y+=t[now].y; ans.xy+=t[now].xy;ans.x2+=t[now].x2; return; } int mid=(l+r)>>1; pushdown(l,r,now); if(L<=mid) ask(L,R,l,mid,now<<1); if(R>mid) ask(L,R,mid+1,r,now<<1|1);}inline double solve(int L,int R){ ans.x=ans.y=ans.xy=ans.x2=0; ask(L,R,1,n,1); double a=(R-L+1)*ans.xy-ans.x*ans.y; double b=(R-L+1)*ans.x2-ans.x*ans.x; return a/b;}int main(){ freopen("relative.in","r",stdin); freopen("relative.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) a[i]=a[i-1]+i,b[i]=b[i-1]+1.0*i*i; for(int i=1;i<=n;i++) scanf("%lf",&X[i]); for(int i=1;i<=n;i++) scanf("%lf",&Y[i]); build(1,n,1); while(m--) { scanf("%d%d%d",&x,&L,&R); if(x==1) printf("%.10lf\n",solve(L,R)); else if(x==2) scanf("%d%d",&y,&z),add1(L,R,1,n,1,y,z); else scanf("%d%d",&y,&z),add2(L,R,1,n,1,y,z); } return 0;}
0 0
- SDOI2017Day2T3 相关分析
- 相关分析
- 相关分析
- 相关分析
- 相关分析
- 相关分析
- 相关分析
- 典型相关分析相关资料
- 相关分析和回归分析
- 相关分析与回归分析
- BPM相关热点分析
- 中文搜索相关分析
- 相关分析总结
- 语料分析相关概念
- 方差分析与相关分析
- OGRE资源相关分析
- OGRE资源相关分析
- OGRE资源相关分析
- Map集合的四种遍历方式
- Ubuntu下QT的安装详细教程
- js自定义函数名不可以命名为click
- 河工大校赛终结
- LeetCode:217. Contains Duplicate
- SDOI2017Day2T3 相关分析
- PostgreSQL 新手入门
- 重定向与转发的区别以及什么时候使用
- Java基础学习笔记:(七)this关键字
- 虚拟文件系统
- 《将博客搬至CSDN》
- 对Java Serializable(序列化)的理解和总结
- 程序设计与计算机系统-笔记
- Vim插件之Vebugger