zoukankan      html  css  js  c++  java
  • [HAOI2012]高速公路

    [HAOI2012]高速公路

    有N-1段路和N个点组成的链,方向从小到大,点上有权值,定义一条边的边权为其入点的点权,M次操作,区间修改和询问点l到r的子路径的边权和期望,(N,Mleq 100000)

    显然需要链转区间,于是修改l,r不变,询问--r即可变为区间问题,现在问题是求l-r的子区间和的期望,显然概率固定,考虑公式法,而需要输出分数形式,对于分母不难得知为(C_{r-l+2}^2),现在关键在于维护方案乘以随机变量,于是列式维护,不难得知,所求即((s_0)为前缀和,a为一个位置的值)

    [sum_{i=l}^rsum_{j=i+1}^r(s[j]-s[i-1]) ]

    显然这样是无法维护的,考虑单个点不难有

    [sum_{i=l}^ra_i(r-i+1)(i-l+1)=sum_{i=l}^ra_i(r-l-rl+1+il+ri-i^2)= ]

    [sum_{i=l}^ra_i(r-l-rl+1)+sum_{i=l}^ria_i(r+l)-sum_{i=l}^ri^2a_i ]

    于是设(s_1[n]=sum_{i=1}^nia_i,s2[n]=sum_{i=1}^ni^2a_i),显然它们具有区间合并性,而维护只需要加上(sum i,sum i^2)的区间和乘以修改值,接着根据得到的三个式子求出我们所需的ans,再与总方案约分,输出答案即可。

    参考代码:

    #include <iostream>
    #include <cstdio>
    #define il inline
    #define ri register
    #define ll long long
    #define swap(x,y) x^=y^=x^=y
    using namespace std;
    il void read(int&),get(char&),pen(ll);
    il ll gaos(ll),pows(ll),cn2(ll),gcd(ll,ll);
    struct segment_tree{
        struct Data{
            int l,r;ll s[3],a;
        }t[400001];
        il void build(int p,int l,int r){
            t[p].l=l,t[p].r=r;if(l==r)return;
            int mid(l+r>>1),pl(p<<1),pr(pl|1);
            build(pl,l,mid),build(pr,mid+1,r);
        }
        il void spread(int p){
            if(t[p].a){
                int pl(p<<1),pr(pl|1);t[pl].a+=t[p].a,t[pr].a+=t[p].a;
                t[pl].s[0]+=(t[pl].r-t[pl].l+1)*t[p].a,t[pr].s[0]+=(t[pr].r-t[pr].l+1)*t[p].a;
                t[pl].s[1]+=(gaos(t[pl].r)-gaos(t[pl].l-1))*t[p].a,t[pr].s[1]+=(gaos(t[pr].r)-gaos(t[pr].l-1))*t[p].a;
                t[pl].s[2]+=(pows(t[pl].r)-pows(t[pl].l-1))*t[p].a,t[pr].s[2]+=(pows(t[pr].r)-pows(t[pr].l-1))*t[p].a;
                t[p].a&=0;
            }
        }
        il void change(int p,int l,int r,int v){
            if(l<=t[p].l&&t[p].r<=r){
                t[p].a+=v,t[p].s[0]+=(t[p].r-t[p].l+1)*v;
                t[p].s[1]+=(gaos(t[p].r)-gaos(t[p].l-1))*v;
                t[p].s[2]+=(pows(t[p].r)-pows(t[p].l-1))*v;
                return;
            }spread(p);int mid(t[p].l+t[p].r>>1),pl(p<<1),pr(pl|1);
            if(l<=mid)change(pl,l,r,v);if(mid<r)change(pr,l,r,v);
            t[p].s[0]=t[pl].s[0]+t[pr].s[0],t[p].s[1]=t[pl].s[1]+t[pr].s[1],t[p].s[2]=t[pl].s[2]+t[pr].s[2];
        }
        il ll asks0(int p,int l,int r){
            if(l<=t[p].l&&t[p].r<=r)return t[p].s[0];spread(p);
            ll ans(0);int mid(t[p].l+t[p].r>>1),pl(p<<1),pr(pl|1);
            if(l<=mid)ans+=asks0(pl,l,r);if(mid<r)ans+=asks0(pr,l,r);
            return ans;
        }
        il ll asks1(int p,int l,int r){
            if(l<=t[p].l&&t[p].r<=r)return t[p].s[1];spread(p);
            ll ans(0);int mid(t[p].l+t[p].r>>1),pl(p<<1),pr(pl|1);
            if(l<=mid)ans+=asks1(pl,l,r);if(mid<r)ans+=asks1(pr,l,r);
            return ans;
        }
        il ll asks2(int p,int l,int r){
            if(l<=t[p].l&&t[p].r<=r)return t[p].s[2];spread(p);
            ll ans(0);int mid(t[p].l+t[p].r>>1),pl(p<<1),pr(pl|1);
            if(l<=mid)ans+=asks2(pl,l,r);if(mid<r)ans+=asks2(pr,l,r);
            return ans;
        }
        il ll ask(ll l,ll r){
            ll son,mom,d;
            son=(r-l*r-l+1)*asks0(1,l,r)+(l+r)*asks1(1,l,r)-asks2(1,l,r);
            mom=cn2(r-l+2),d=gcd(son,mom),son/=d,mom/=d;
            pen(son),putchar('/'),pen(mom),putchar('
    ');
        }
    }T;
    int main(){
        int n,m,l,r,lsy;char c;
        read(n),read(m),T.build(1,1,n);
        while(m--){
            get(c),read(l),read(r),--r;
            if(c=='C')read(lsy),T.change(1,l,r,lsy);
            else T.ask(l,r);
        }
        return 0;
    }
    il ll gcd(ll a,ll b){
        while(b)swap(a,b),b%=a;return a;
    }
    il ll cn2(ll n){
        return n*(n-1)/2;
    }
    il void pen(ll x){
        if(x>9)pen(x/10);putchar(x%10+48);
    }
    il void get(char &c){
        while(c=getchar(),c==' '||c=='
    '||c=='
    ');
    }
    il void read(int &x){
        x&=0;ri char c;while(c=getchar(),c==' '||c=='
    '||c=='
    ');
        bool check(false);if(c=='-')check|=true,c=getchar();
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
        if(check)x=~x+1;
    }
    il ll pows(ll n){
        return n*(1+n)*(2*n+1)/6;
    }
    il ll gaos(ll n){
        return n*(1+n)/2;
    }
    
    
  • 相关阅读:
    C++优化和计算速度(碎碎念)
    架设一个p2p存储网络的问题(讨论)
    JAVA做敏感词统计——DFA 算法
    卸载Postman,用IntelliJ IDEA发起http请求
    LPC1788SDRAM调试
    ASP.NET网站大附件上传配置
    K2 Blackpearl中从数据库直接删除流程实例之K2Server表
    K2流程实例出错,切换到其他版本运行
    使用K2时提示未能加载文件或程序集Microsoft.IdentityModel等
    K2 Blackpearl中从数据库直接删除流程实例之K2ServerLog表
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/10850039.html
Copyright © 2011-2022 走看看