zoukankan      html  css  js  c++  java
  • hdu6315 Naive Operations

    题目链接:戳我

    给你两个序列a,b,其中a初始是全空的,b是一个排列。
    现在有两种操作:
    1、给一个区间的a数组加上1
    2、求一个区间(sum a[i]/b[i])
    区间操作想到用数据结构维护。
    我们可以知道,(a[i]/b[i])只有在a[i]增加够一个b[i]的时候才会多1的贡献,但是我们再增加a[i]的时候和b[i]进行比较比较麻烦(但其实也应该是可以做的),所以我们考虑转化成b[i]-1。
    如果b[i]的区间最小值大于1,直接区间减法即可。如果不是,那么寻找那个值为1的,把它改成初始b[i]。
    具体见代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define MAXN 100010
    using namespace std;
    inline int read()
    {
        int 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<<1)+(x<<3)+(ch^48); ch=getchar();}
        return x*f;
    }
    int n,q;
    int a[MAXN],b[MAXN];
    struct Node{long long sum,valb,minn,tag;}t[MAXN<<2];
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    inline void push_up(int x)
    {
        t[x].minn=min(t[ls(x)].minn,t[rs(x)].minn);
        t[x].sum=t[ls(x)].sum+t[rs(x)].sum;
    }
    inline void push_down(int x)
    {
        if(t[x].tag)
        {
            t[ls(x)].tag+=t[x].tag;
            t[rs(x)].tag+=t[x].tag;
            t[ls(x)].minn-=t[x].tag;
            t[rs(x)].minn-=t[x].tag;
            t[x].tag=0;
        }
    }
    inline void build(int x,int l,int r)
    {
        t[x].tag=t[x].sum=0;
        if(l==r)
        {
            t[x].minn=t[x].valb=b[l];
            t[x].sum=0;
            return;
        }
        int mid=(l+r)>>1;
        build(ls(x),l,mid);
        build(rs(x),mid+1,r);
        push_up(x);
    }
    inline void update(int x,int l,int r,int ll,int rr)
    {
        if(ll<=l&&r<=rr&&t[x].minn>1)
        {
            t[x].tag++;
            t[x].minn--;
            return;
        }
        if(l==r&&t[x].minn==1)
        {
            t[x].sum++;
            t[x].minn=t[x].valb;
            t[x].tag=0;
            return;
        }
        int mid=(l+r)>>1;
        push_down(x);
        if(ll<=mid) update(ls(x),l,mid,ll,rr);
        if(mid<rr) update(rs(x),mid+1,r,ll,rr);
        push_up(x);
    }
    inline long long query(int x,int l,int r,int ll,int rr)
    {
        if(ll<=l&&r<=rr) return t[x].sum;
        int mid=(l+r)>>1;
        push_down(x);
        long long cur_ans=0;
        if(ll<=mid) cur_ans+=query(ls(x),l,mid,ll,rr);
        if(mid<rr) cur_ans+=query(rs(x),mid+1,r,ll,rr);
        return cur_ans;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&q))
        {
            for(int i=1;i<=n;i++) b[i]=read();
            build(1,1,n);
            while(q--)
            {
                string str;
                cin>>str;
                // cout<<str<<endl;
                int l=read(),r=read();
                if(str[0]=='a') update(1,1,n,l,r);
                else printf("%lld
    ",query(1,1,n,l,r));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    [COI2007] Patrik 音乐会的等待 单调栈
    [NOI2012]随机数生成器 矩阵乘法
    流程控制主while,for,python画金字塔,画9*9乘法表
    VS第一天(一堆错误的错误示范)
    markdown插入表格语法
    格式化输出,基本运算符,流程控制主if
    jupyter notebook的插件安装及文本格式修改
    7个好用的社交分享按钮代码片段
    标签页tab.js 在栏目之间切换,局部变化
    详解 CSS 属性
  • 原文地址:https://www.cnblogs.com/fengxunling/p/11129406.html
Copyright © 2011-2022 走看看