zoukankan      html  css  js  c++  java
  • LOJ#6029「雅礼集训 2017 Day1」市场

    https://loj.ac/p/6029

    知识点:1.区间除法 (极限   ,势能分析)

        2.除法 -> 减法 (类似有乘法 -> 加法 ,除法 -> 减法, 求幂->乘法)

        3.极限   最多可能操作次数

    #include <bits/stdc++.h>
    #define int long long 
    using namespace std;
    int n,m;
    int a[100010];
    int tre[400010],lazy[400010],maxn[400010],minn[400010];
    int cal (int num,int k)
    {
        if(num >= 0)
        {
            return num - (num / k);
        }
        else if(num < 0)
        {
            int h = -num;
            int cha = h - ((h + k - 1) / k);
            return -cha;
        }
    }
    void down(int t,int l,int r,int k)
    {
        tre[t] += (r - l + 1) * k;
        lazy[t] += k;
        maxn[t] += k;
        minn[t] += k;
        return ;
    }
    void up(int t,int l,int r)
    {
        int mid = (l + r) >> 1;
        down(t << 1,l,mid,lazy[t]);
        down((t << 1) + 1,mid + 1,r,lazy[t]);
        lazy[t] = 0;
        return;
    } 
    void built(int t,int l,int r)
    {
        if(l == r)
        {
            maxn[t] = a[l];
            minn[t] = a[l];
            tre[t] = a[l];
            lazy[t] = 0;
            return ;
        }
        int mid = (l + r) >> 1;
        built(t << 1,l,mid);
        built((t << 1) + 1,mid + 1,r);
        tre[t] = tre[t << 1] + tre[(t << 1) + 1];
        maxn[t] = max(maxn[t << 1],maxn[(t << 1) + 1]);
        minn[t] = min(minn[t << 1],minn[(t << 1) + 1]);
        return ;
    }
    void updatajia(int t,int l,int r,int L,int R,int k)
    {
        if(L <= l && r <= R)
        {
            tre[t] += (r - l + 1) * k;
            lazy[t] += k;
            maxn[t] += k;
            minn[t] += k;
            return; 
        }
        int mid = (l + r) >> 1;
        up(t,l,r);
        if(L <= mid)updatajia(t << 1,l,mid, L,R,k);
        if(mid < R)updatajia((t << 1) + 1,mid + 1,r,L,R,k);
        tre[t] = tre[t << 1] + tre[(t << 1) + 1];
        maxn[t] = max(maxn[t << 1],maxn[(t << 1) + 1]);
        minn[t] = min(minn[t << 1],minn[(t << 1) + 1]);
        return;
    }
    int query(int t,int l,int r,int L,int R)
    {
        if(L <= l && r <= R)
        {
            return tre[t];
        }
        int mid = (l + r) >> 1;
        up(t,l,r);
        int ret = 0;
        if(L <= mid)ret += query(t << 1,l,mid,L,R);
        if(mid < R)ret += query((t << 1) + 1,mid + 1,r,L,R);
        return ret; 
    }
    int querymin(int t,int l,int r,int L,int R)
    {
        if(L <= l && r <= R)
        {
            return minn[t];
        }
        int mid = (l + r) >> 1;
        up(t,l,r);
        int ret = 999999999;
        if(L <= mid)ret = min(ret,querymin(t << 1,l,mid,L,R));
        if(mid < R)ret = min(ret,querymin((t << 1) + 1,mid + 1,r,L,R));
        return ret; 
    }
    void updatachu(int t,int l,int r,int L,int R,int k)
    {
        if(L <= l && r <= R)
        {
            int maxcha = cal(maxn[t],k);
            int mincha = cal(minn[t],k);
            if(maxcha == mincha)
            {
                int kk = maxcha;
                tre[t] += (r - l + 1) * (-kk);
                lazy[t] += (-kk);
                maxn[t] += (-kk);
                minn[t] += (-kk);
                return;
            }
        }
        int mid = (l + r) >> 1;
        up(t,l,r);
        if(L <= mid)updatachu(t << 1,l,mid,L,R,k);
        if(mid < R)updatachu((t << 1) + 1,mid + 1,r,L,R,k);
        tre[t] = tre[t << 1] + tre[(t << 1) + 1];
        maxn[t] = max(maxn[t << 1],maxn[(t << 1) + 1]);
        minn[t] = min(minn[t << 1],minn[(t << 1) + 1]);
        //lazy not ;
        return ;
    }
    signed main()
    {
        scanf("%lld%lld",&n,&m);
        for(int i = 1;i <= n;i++)
        {
            scanf("%lld",&a[i]);
        }
        int x,y,j,z;
        built(1,1,n);
        while(m--)
        {
            scanf("%lld%lld%lld",&x,&y,&j);
            if(x == 1)
            {
                scanf("%lld",&z);
                updatajia(1,1,n,y + 1,j + 1,z);    
            }    
            else if(x == 2)
            {
                scanf("%lld",&z);
                updatachu(1,1,n,y + 1,j + 1,z);
            }
            else if(x == 3)
            {
                printf("%lld
    ",querymin(1,1,n,y + 1,j + 1));
            }
            else if(x == 4)
            {
                printf("%lld
    ",query(1,1,n,y + 1,j + 1));
            }
        }
        return 0;
    }
  • 相关阅读:
    Documentum常见问题1—Tomcat应用内存溢出
    Documentum常见问题3—保存搜索Saved Searches提示用户对文件柜无权限
    Request.QueryString[]和Request[]的区别
    将money转换成大写汉字
    Windows API(一) 什么是Windows API
    C#将数据导出到Excel汇总
    开始—运行—命令
    手动绘制DataTable
    触发器Deleted表和Inserted表
    功能强大的Regsvr32命令
  • 原文地址:https://www.cnblogs.com/xyj1/p/14821780.html
Copyright © 2011-2022 走看看