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;
    }
    
  • 相关阅读:
    【liunx】使用xshell连接虚拟机上的CentOS 7,使用xhell连接本地虚拟机上的Ubuntu, 获取本地虚拟机中CentOS 7的IP地址,获取本地虚拟机中Ubuntu 的IP地址,linux查看和开启22端口
    eclipse启动tomcat, http://localhost:8080无法访问
    java合并PDF,itext.jar
    关于给springboot添加定时器的两种方式
    HttpClient post提交数据,汉字转码
    java 中文与unicode互转
    微信公众号里的图片下载并显示
    根据url下载图片和页面
    java获取指定日期之前或之后的时间
    java计算文件大小
  • 原文地址:https://www.cnblogs.com/fengxunling/p/11129406.html
Copyright © 2011-2022 走看看