• [HAOI2012]高速公路 [线段树 期望]


    [HAOI2012]高速公路

    bzoj2752 luogu2221

    Y901高速公路是一条由N-1段路以及N个收费站组成的东西向的链,我们按照由西向东的顺序将收费站依次编号为1~N,从收费站i行驶到i+1(或从i+1行驶到i)需要收取Vi的费用。高速路刚建成时所有的路段都是免费的。

    政府部门根据实际情况,会不定期地对连续路段的收费标准进行调整,根据政策涨价或降价。

    无聊的小A同学总喜欢研究一些稀奇古怪的问题,他开车在这条高速路上行驶时想到了这样一个问题:对于给定的l,r(l<r),在第l个到第r个收费站里等概率随机取出两个不同的收费站a和b,那么从a行驶到b将期望花费多少费用呢?

    一条链 每次询问区间([l,r])中期望花费

    区间([l,r])的期望花费 即一个平均值(egin{align*}frac{sum_{i=l}^rsum_{j=i}^rdis[i][j]}{{r-l+1choose 2}}end{align*}) (因为(dis[i][j],(i>j))的情况和((i<j))的情况是一样的 求平均值 就不用再多算一遍了

    考虑第(i)条边的贡献 它总共在((i-l+1)(r-i+1))个区间内 所以化简为(sum_iw[i](i-l+1)(r-i+1))

    我将(w[i])表示(i-1 o i)的道路花费 所以第(i)条边在区间([l,r])内贡献了 (w[i]*(i-l+1)(r-i)=w[i]* i *(l+r-1)-w[i]*i^2+r*(1-l))

    即线段树(sum w[i]*i,sum w[i]*i^2,sum w[i])

    然后注意一些小细节就好 对,注意(l*l)要爆int QAQ

    struct node{ll sum1,sum2,sum3,add,pre1,pre2;}t[N<<2];
    void pup(int o){
    	t[o].sum1=t[ls].sum1+t[rs].sum1,t[o].sum2=t[ls].sum2+t[rs].sum2,t[o].sum3=t[ls].sum3+t[rs].sum3;
    }
    void updnode(int o,int l,int r,ll k){
    	t[o].sum1+=k*t[o].pre1,t[o].sum2+=k*t[o].pre2,t[o].sum3+=((ll)r-l+1)*k,t[o].add+=k;
    }
    void pudw(int o,int l,int r){
    	if(!t[o].add) return;
    	int mid=l+r>>1;
    	updnode(ls,l,mid,t[o].add),updnode(rs,mid+1,r,t[o].add),t[o].add=0;
    }
    void upd(int o,int l,int r,int x,int y,ll k){
    	if(x>r||y<l) return;
    	if(x<=l&&r<=y){updnode(o,l,r,k);return;}
    	pudw(o,l,r);
    	int mid=l+r>>1;
    	upd(ls,l,mid,x,y,k),upd(rs,mid+1,r,x,y,k);
    	pup(o);
    }
    ll d,ans1,ans2,sum1,sum2,sum3;
    void query(int o,int l,int r,int x,int y){
    	if(x>r||y<l) return;
    	if(x<=l&&r<=y){sum1+=t[o].sum1,sum2+=t[o].sum2,sum3+=t[o].sum3;return;}
    	pudw(o,l,r);
    	int mid=l+r>>1;
    	query(ls,l,mid,x,y),query(rs,mid+1,r,x,y);
    	pup(o);
    	
    }
    void build(int o,int l,int r){
    	if(l==r){t[o]=(node){0,0,0,0,l,(ll)l*l};return;}
    	int mid=l+r>>1;
    	build(ls,l,mid),build(rs,mid+1,r);
    	t[o].pre1=t[ls].pre1+t[rs].pre1,t[o].pre2=t[ls].pre2+t[rs].pre2;
    }
    ll gcd(ll x,ll y){return !y?x:gcd(y,x%y);}
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
    	rd(n),rd(m);
    	char opt[5];
    	build(1,1,n);
    	for(int i=1,x,y,k;i<=m;++i){
    		scanf("%s",opt);rd(x),rd(y),--y;
    		if(opt[0]=='C'){
    			rd(k);
    			upd(1,1,n,x,y,(ll)k);
    		}
    		else{
    			sum1=sum2=sum3=0ll;query(1,1,n,x,y);++y;
    			ans1=sum1*((ll)y+x-1)-sum2+(ll)y*(1-x)*sum3,ans2=((ll)y-x)*((ll)y-x+1)/2;
    			d=gcd(ans1,ans2),ans1/=d,ans2/=d;
    			if(!ans1) puts("0/1");
    			else printf("%lld/%lld
    ",ans1,ans2);
    		}
    	}
        return 0; 
    }
    
  • 相关阅读:
    Table.Combine追加…Combine(Power Query 之 M 语言)
    Table.NestedJoin合并…Join(Power Query 之 M 语言)
    Delphi Post登陆Delphi盒子论坛源码
    分享一个函数GetStr
    用友生产工艺路线导入工具1.1
    笔下文学小说下载【3.01】 发布
    U6 3.2盘点单管理1.01
    防止SQL SERVER的事件探查器跟踪软件
    双系统的安装(原创)
    2345导航自动登陆签到【1.01】
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11647746.html
Copyright © 2020-2023  润新知