bzoj 2752: [HAOI2012]高速公路(road) 线段树
2017-02-13 19:38
302 查看
题意
有一条链,要求资磁两个操作C l r v 表示将第l个收费站到第r个收费站之间的所有道路的通行费全部增加v
Q l r 表示对于给定的l,r,要求回答对于给定的l,r(l < r),在第l个到第r个收费站里等概率随机取出两个不同的收费站a和b,那么从a行驶到b将期望花费多少费用呢?
n,q<=100000
分析
把边变成点,那么答案就是∑val[i]∗(i−l+1)∗(r−i+1)(r−l+1)∗(r−l)/2现在的问题是如何维护分子上的那个值。
对于一颗线段树,我们每个节点维护sum表示这个区间的权值和,val表示∑val[i]∗(i−l+1)∗(r−i+1),lsum表示1∗val[l]+2∗val[l+1]+...+(r−l+1)∗val[r],rsum同理
然后各种乱搞即可。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define N 100005 #define LL long long using namespace std; int n,m,root,tot; struct tree{int l,r;LL val,lsum,rsum,sum,tag;}t[N*4]; int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } LL gcd(LL x,LL y) { if (!y) return x; else return gcd(y,x%y); } void pushdown(int d,int l,int r) { if (!t[d].tag||l==r) return; int mid=(l+r)/2,len=mid-l+1; LL c=t[d].tag; if (!t[d].l) t[d].l=++tot; t[t[d].l].sum+=(LL)len*c; t[t[d].l].lsum+=(LL)len*(len+1)/2*c; t[t[d].l].rsum+=(LL)len*(len+1)/2*c; t[t[d].l].val+=(LL)((LL)len*len*(len+1)/2-(LL)len*(len-1)*(len+1)/3)*c; t[t[d].l].tag+=c; len=r-mid; if (!t[d].r) t[d].r=++tot; t[t[d].r].sum+=(LL)len*c; t[t[d].r].lsum+=(LL)len*(len+1)/2*c; t[t[d].r].rsum+=(LL)len*(len+1)/2*c; t[t[d].r].val+=(LL)((LL)len*len*(len+1)/2-(LL)len*(len-1)*(len+1)/3)*c; t[t[d].r].tag+=c; t[d].tag=0; } void updata(int d,int l,int r) { int mid=(l+r)/2,lenl=mid-l+1,lenr=r-mid; t[d].sum=t[t[d].l].sum+t[t[d].r].sum; t[d].lsum=t[t[d].l].lsum+t[t[d].r].lsum+(LL)t[t[d].r].sum*lenl; t[d].rsum=t[t[d].r].rsum+t[t[d].l].rsum+(LL)t[t[d].l].sum*lenr; t[d].val=t[t[d].l].val+t[t[d].r].val+(LL)t[t[d].l].lsum*lenr+(LL)t[t[d].r].rsum*lenl; } void ins(int &d,int l,int r,int x,int y,int v) { if (!d) d=++tot; pushdown(d,l,r); int len=r-l+1,mid=(l+r)/2; if (l==x&&r==y) { t[d].sum+=(LL)len*v; t[d].lsum+=(LL)len*(len+1)/2*v; t[d].rsum+=(LL)len*(len+1)/2*v; t[d].val+=(LL)((LL)len*len*(len+1)/2-(LL)len*(len-1)*(len+1)/3)*v; t[d].tag+=v; return; } if (y<=mid) ins(t[d].l,l,mid,x,y,v); else if (x>mid) ins(t[d].r,mid+1,r,x,y,v); else { ins(t[d].l,l,mid,x,mid,v); ins(t[d].r,mid+1,r,mid+1,y,v); } updata(d,l,r); } void query(int d,int l,int r,int x,int y,LL &val,LL &lsum,LL &rsum,LL &sum) { if (!d) { val=lsum=rsum=sum=0; return; } pushdown(d,l,r); if (l==x&&r==y) { val=t[d].val;lsum=t[d].lsum;rsum=t[d].rsum;sum=t[d].sum; return; } int mid=(l+r)/2; if (y<=mid) query(t[d].l,l,mid,x,y,val,lsum,rsum,sum); else if (x>mid) query(t[d].r,mid+1,r,x,y,val,lsum,rsum,sum); else { LL val1,lsum1,rsum1,sum1,val2,lsum2,rsum2,sum2; query(t[d].l,l,mid,x,mid,val1,lsum1,rsum1,sum1); query(t[d].r,mid+1,r,mid+1,y,val2,lsum2,rsum2,sum2); int len1=mid-x+1,len2=y-mid; val=val1+(LL)lsum1*len2+val2+(LL)rsum2*len1; lsum=lsum1+lsum2+(LL)sum2*len1; rsum=rsum1+rsum2+(LL)sum1*len2; sum=sum1+sum2; } } int main() { n=read();m=read(); n--; for (int i=1;i<=m;i++) { char ch[2]; scanf("%s",ch); if (ch[0]=='C') { int l=read(),r=read(),v=read(); r--; ins(root,1,n,l,r,v); } else { int l=read(),r=read(),len=r-l+1;r--; LL x,y=(LL)len*(len-1)/2,lsum,rsum,sum; query(root,1,n,l,r,x,lsum,rsum,sum); LL d=gcd(x,y); printf("%lld/%lld\n",x/d,y/d); } } return 0; }
相关文章推荐
- bzoj 2752: [HAOI2012]高速公路(road) 线段树
- BZOJ 2752 [HAOI2012]高速公路(road)【线段树
- 【bzoj2752】[HAOI2012]高速公路(road) 线段树
- BZOJ 2752 [HAOI2012]高速公路(road) 线段树
- bzoj 2752: [HAOI2012]高速公路(road) (线段树)
- [线段树 期望] BZOJ 2752: [HAOI2012]高速公路(road)
- bzoj 2752 [HAOI2012]高速公路(road) 线段树
- BZOJ 2752: [HAOI2012]高速公路(road)( 线段树 )
- 【BZOJ2752】[HAOI2012]高速公路(road) 线段树
- [BZOJ]2752: [HAOI2012]高速公路(road) 线段树
- 【线段树】BZOJ2752: [HAOI2012]高速公路(road)
- BZOJ 2752: [HAOI2012]高速公路(road) [线段树 期望]
- BZOJ 2752 [HAOI2012]高速公路(road) | 线段树 期望
- bzoj2752 [HAOI2012]高速公路(road)
- ●BZOJ 2752 [HAOI2012]高速公路(road)
- BZOJ2752 [HAOI2012]高速公路(road)
- bzoj 2752: [HAOI2012]高速公路(road)
- 【BZOJ】【2752】【HAOI2012】高速公路(Road)
- BZOJ2752: [HAOI2012]高速公路(road)
- BZOJ 2752: [HAOI2012]高速公路(road)