hdu多校第二场:6315 (线段树暴力)

题目大意:

给你一串b数组,数组中的数为1到n,顺序可能被打乱。a数组初始化为0,有两种操作

操作1:对于l r区间的a数组+1

操作2:查询l r之间的 ai/bi 向下取整。

解题思路:

这道题比赛卡了一下午,搞蒙了,很早的时候想出了维护最少需要升级经验的正解,但是和队友讨论感觉会T啊,因为有1这些数在,总感觉复杂度不对劲,后来想了一大堆其他做法也没做出来,然后又转回去写第一种想法,写到一半的时候自认为想出了一种更简单的写法,写了以后T了,然后就这样了= = 就没再管第一种写法。。。结果赛后写了以后AC。。。

惨淡2题收尾。

我们认为一个数升级所需的经验就是他们自己的大小,升级代表当前res++。

其实就是维护区间升级所需的最少经验值,当这个值为负数的时候就需要更新到子节点去将答案更新。

这个复杂度真的不会证啊,莫名其妙就过了= = 

要是早知道也不会卡5个消失了 。。。

Ac代码:

#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn=1e5+5;
const int INF=1e9+7;
int n,m,ans,a[maxn];
char s[100];
struct node
{
    int l,r,mid,val;	//val升级所需经验 sum当前区间获得经验 res当前答案总和
    int sum,res;
}t[maxn<<2];
void pushup(int rt)	//val取最小值
{
    t[rt].res=t[lson].res+t[rson].res;
    t[rt].val=min(t[lson].val,t[rson].val);
}
void pushdown(int rt)	//val记得更新
{
    if(t[rt].sum)
    {
        t[lson].sum+=t[rt].sum;
        t[lson].val-=t[rt].sum;
        t[rson].sum+=t[rt].sum;
        t[rson].val-=t[rt].sum;
        t[rt].sum=0;
        return ;
    }
}
void build(int l,int r,int rt)
{
    int mid=(l+r)>>1;
    t[rt].l=l,t[rt].r=r,t[rt].mid=mid;
    t[rt].val=t[rt].sum=t[rt].res=0;
    if(l==r)
    {
        t[rt].val=a[l];	//默认升级经验为自己的大小
        return ;
    }
    build(l,mid,lson);
    build(mid+1,r,rson);
    pushup(rt);
}
void update(int l,int r,int rt)
{
    if(l<=t[rt].l&&t[rt].r<=r)
    {
        t[rt].sum++;	//更新val 和 sum
        t[rt].val--;
        return ;
    }
    pushdown(rt);
    if(l<=t[rt].mid) update(l,r,lson);
    if(r>t[rt].mid) update(l,r,rson);
    pushup(rt);
}
void query(int l,int r,int rt)
{
    if(l<=t[rt].l&&t[rt].r<=r&&t[rt].val>0)	//表示当前区间没有需要更新的
    {
        ans+=t[rt].res;
        return;
    }
    if(t[rt].l==t[rt].r)	//更新到叶子结点
    {
        if(t[rt].val<=0)
        {
            t[rt].val+=t[rt].sum;	//将val还原
            t[rt].res++;	//答案++
            t[rt].sum-=t[rt].val;	//sum减去val
            t[rt].res+=t[rt].sum/a[t[rt].r];	//处理出新的res以及val
            t[rt].val=a[t[rt].r]-t[rt].sum%a[t[rt].r];
            t[rt].sum=0;
        }
        ans+=t[rt].res;
        return ;
    }
    pushdown(rt);
    if(l<=t[rt].mid)query(l,r,lson);
    if(r>t[rt].mid)query(l,r,rson);
    pushup(rt);
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        build(1,n,1);
        while(m--)
        {
            int l,r;
            scanf("%s%d%d",s,&l,&r);
            if(s[0]=='a')update(l,r,1);
            else
            {
                ans=0;
                query(l,r,1);
                printf("%d\n",ans);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/f2935552941/article/details/81210118