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);
            }
        }
    }
}

 

發佈了146 篇原創文章 · 獲贊 14 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章