zoukankan      html  css  js  c++  java
  • ●BZOJ 2752 [HAOI2012]高速公路(road)

    题链:

    http://www.lydsy.com/JudgeOnline/problem.php?id=2752
    题解:

    期望,线段树。
    把每个路段看成一个点,那么对于l~R的操作,就可以转化为对l~r(r=R-1)的路段的操作。
    对于每个询问,我们只需要依次考虑每个路段出现在多少个区间里面。
    令cnt[i]表示i号路段在cnt[i]个区间包含。
    即答案为$$frac{sum_{i=l}^{r}v[i]*cnt[i]}{(r-l+1)*(r-l+2)/2(区间总数)}$$
    那么就需要在线维护一些,使得能够快速求出上面的值。
    考虑每个路段的贡献:
    i号路段被(i-l+1)*(r-i+1)个区间包含,
    所以贡献为:(i-l+1)*(r-i+1)*v[i],把其展开:
    =(l+r)*i*v[i]-l*r*v[i]-l*v[i]+r*v[i]-i*i*v[i]+v[i]。
    所以,我们只需要用线段树维护每个区间的路段的v[i]的和,i*v[i]的和,i*i*v[i]的和;


    代码:

    #include<bits/stdc++.h>
    #define MAXN 100005
    using namespace std;
    long long sumi[MAXN],sumi2[MAXN];
    struct SGT{
    	int size,root;
    	int ls[MAXN*2],rs[MAXN*2],lazy[MAXN*2];
    	long long sumval[MAXN*2],sumival[MAXN*2],sumi2val[MAXN*2];
    	void Pushup(int u){
    		sumval[u]=sumval[ls[u]]+sumval[rs[u]];
    		sumival[u]=sumival[ls[u]]+sumival[rs[u]];
    		sumi2val[u]=sumi2val[ls[u]]+sumi2val[rs[u]];
    	}
    	void Add(int &u,int l,int r,int v){
    		if(!u) u=++size;
    		sumval[u]+=1ll*(r-l+1)*v;
    		sumival[u]+=(sumi[r]-sumi[l-1])*v;
    		sumi2val[u]+=(sumi2[r]-sumi2[l-1])*v;
    		lazy[u]+=v;
    	}
    	void Pushdown(int u,int l,int mid,int r){
    		Add(ls[u],l,mid,lazy[u]);
    		Add(rs[u],mid+1,r,lazy[u]);
    		lazy[u]=0;
    	}
    	void Modify(int &u,int l,int r,int al,int ar,int v){
    		if(!u) u=++size;
    		if(al<=l&&r<=ar) return Add(u,l,r,v);
    		int mid=(l+r)>>1;
    		if(lazy[u]) Pushdown(u,l,mid,r);
    		if(al<=mid) Modify(ls[u],l,mid,al,ar,v);
    		if(mid<ar) Modify(rs[u],mid+1,r,al,ar,v);
    		Pushup(u);
    	}
    	long long Contribution(int u,int al,int ar){
    		return sumival[u]*(al+ar)-sumval[u]*al*ar-sumval[u]*al+sumval[u]*ar-sumi2val[u]+sumval[u];
    //		return sumival[u]*(al+ar)-sumval[u]*al*ar+sumval[u]*ar-sumival[u]-sumi2val[u];
    	}
    	long long Query(int u,int l,int r,int al,int ar){
    		if(!u) return 0;
    		if(al<=l&&r<=ar) return Contribution(u,al,ar);
    		int mid=(l+r)>>1; long long ret=0;
    		if(lazy[u]) Pushdown(u,l,mid,r);
    		if(al<=mid) ret+=Query(ls[u],l,mid,al,ar);
    		if(mid<ar) ret+=Query(rs[u],mid+1,r,al,ar);
    		return ret;
    	}
    }DT;
    int N,M;
    long long gcd(long long a,long long b){
    	while(b^=a^=b^=a%=b);
    	return a;
    }
    int main(){
    	char ch; int l,r,v;
    	scanf("%d%d",&N,&M);
    	for(int i=1;i<=N;i++)
    		sumi[i]=sumi[i-1]+i,sumi2[i]=sumi2[i-1]+1ll*i*i;
    	for(int i=1;i<=M;i++){
    		scanf(" %c %d %d",&ch,&l,&r); r--;
    		if(ch=='C') scanf("%d",&v),DT.Modify(DT.root,1,N,l,r,v);
    		else {
    			long long a=DT.Query(DT.root,1,N,l,r);
    			long long b=1ll*(r-l+1)*(r-l+2)/2;
    			long long g=gcd(a,b);
    			a/=g; b/=g; printf("%lld/%lld
    ",a,b);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    买书求如何获得折扣使价格最低
    团队开发NABC特点
    《梦断代码》读后感3
    结对开发5
    找水王问题续
    对搜狗输入法的评价
    团队项目之典型用户
    找水王问题
    电梯调度练习
    团队项目用户需求调研报告
  • 原文地址:https://www.cnblogs.com/zj75211/p/8541937.html
Copyright © 2011-2022 走看看