• CH模拟赛 还教室


    /*
    区间操作,可以推一推式子,方差为平方的平均数-平均数的平方,维护区间和与区间平方和,平方和的维护方法类似,式子推一推就行了,注意约分
    */
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #define ll long long
    #define fo(i,l,r) for(int i = l;i <= r;i++)
    #define fd(i,l,r) for(int i = r;i >= l;i--)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int N = 100050;
    ll read(){
        ll 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 a,ll b){return b==0?a:gcd(b,a%b);}
    struct fs{
        ll son;
        ll mo;
        void yf(){
            if(son == 0 || mo == 0){
                if(son == 0) mo = 1;
                return;
            }
            ll d = gcd(son,mo);
            son /= d;
            mo /= d;
        }
        void clear(ll a,ll b){
            son = a;
            mo = b;
            yf();
        }    
        fs operator + (fs b){
            fs a=*this;
            ll d = gcd(a.mo,b.mo);
            ll lcm = a.mo / d * b.mo;
            a.son *= lcm / a.mo;
            b.son *= lcm / b.mo; 
            a.son += b.son;
            a.mo = lcm;
            a.yf();
            return a;
        }
        fs operator - (fs b){
            fs a=*this;
            ll d = gcd(a.mo,b.mo);
            ll lcm = a.mo / d * b.mo;
            a.son *= lcm / a.mo;
            b.son *= lcm / b.mo; 
            a.son -= b.son;
            a.mo = lcm;
            if(!a.son) a.mo = 1;
            else a.yf();
            return a;
        }
        fs operator * (fs b){
            fs a=*this;
            a.son *= b.son;
            a.mo *= b.mo;
            a.yf();
            return a;
        }
        fs operator / (ll b){
            fs a =*this;
            a.mo *= b;
            a.yf();
            return a;
        }
        bool operator < (fs b){
            return son*b.mo < mo*b.son;
        }
        fs operator - (ll k){
            fs b,a=*this;
            b.clear(k,1);
            if(a<b) swap(a,b);
            return a-b;
        }
        void print(){
            printf("%I64d/%I64d
    ",son,mo);
        }
    }ans,fd;
    int n,m;ll val[N];
    ll sumv[N<<4],addv[N<<4],powv[N<<4];
    ll cmd,op,ql,qr,qv,ans1,ans2;
    void maintain(int rt){
        sumv[rt] = sumv[rt<<1] + sumv[rt<<1|1];
        powv[rt] = powv[rt<<1] + powv[rt<<1|1];
    }
    void pushdown(int l,int r,int rt){
        int m = (l + r) >> 1;
        if(!addv[rt]) return;
        addv[rt<<1] += addv[rt];
        addv[rt<<1|1] += addv[rt];
        powv[rt<<1] += 2*addv[rt]*sumv[rt<<1] + (m-l+1)*addv[rt]*addv[rt];
        powv[rt<<1|1] += 2*addv[rt]*sumv[rt<<1|1] + (r-m)*addv[rt]*addv[rt];
        sumv[rt<<1] += addv[rt] * (m-l+1);
        sumv[rt<<1|1] += addv[rt] * (r-m);
        addv[rt] = 0;
    }
    void build(int l,int r,int rt){
        addv[rt] = 0;
        if(l==r){
            powv[rt] = val[l]*val[l];
            sumv[rt] = val[l];
            return;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        maintain(rt);
    }
    void change(ll l,ll r,int rt){
        if(ql <= l && qr >= r){
            addv[rt] += qv;
            powv[rt] += 2*qv*sumv[rt] + qv*qv*(r-l+1);
            sumv[rt] += qv*(r-l+1);
            return;
        }
        pushdown(l,r,rt);
        int m = (l + r) >> 1;
        if(ql <= m) change(lson);
        if(qr > m) change(rson);
        maintain(rt);
    }
    ll query(int l,int r,int rt){
        if(ql <= l && qr >= r){
            if(op == 1) return sumv[rt];
            else return powv[rt];
        }
        pushdown(l,r,rt);
        int m = (l + r) >> 1;
        ll ret = 0;
        if(ql <= m) ret += query(lson);
        if(qr > m) ret += query(rson);
        return ret; 
    }
    int main(){
        freopen("classroom.in","r",stdin);
        freopen("classroom.out","w",stdout);
        n =read();m=read();
        fo(i,1,n) val[i]=read();
        build(1,n,1);
        fo(i,1,m){
            cmd=read();ql=read();qr=read();
            if(cmd==1){
                qv=read();
                change(1,n,1);
            }else if(cmd == 2){
                op = 1;
                ans1=query(1,n,1);
                ans2=(qr-ql+1);
                ans.clear(ans1,ans2);
                ans.print();
            }else if(cmd == 3){
                op = 2;
                ans1=query(1,n,1);
                ans2=(qr-ql+1);
                ans.clear(ans1,ans2);
                ans1=ans2=0;
                op = 1;
                ans1=query(1,n,1);
                ans2=(qr-ql+1);
                fd.clear(ans1,ans2);
                fd = fd*fd;
                ans = ans-fd;
                ans.print();
            }
        }
        return 0;
    } 
  • 相关阅读:
    如何更改VS2005调试网站的浏览器类型
    StringBuilder 的 Capacity属性
    Convert.ToInt32,Int32.Parse和Int32.TryParse的关系
    今天第一天注册
    关于Random产生随机数测试
    [导入]Reporting Services 4: Web Service
    [导入]Reporting Services 5: Extensions & Custom Report Item
    silverlight缓存无法更新的简易解决办法
    总结前段时间做的电话业务故障处理系统(1)
    atlas
  • 原文地址:https://www.cnblogs.com/hyfer/p/6035547.html
Copyright © 2020-2023  润新知