打怪獸

D06發表於2024-07-08
  • 問題之所以看上去很棘手,是因為各種意義上的起始能量值未知
  • 但能量值的上限最多僅為100,因此我們可以透過列舉消去這一維度的資訊,於是需要統計的資訊就可以用線段樹維護了
點選檢視程式碼
#include <bits/stdc++.h> 
using namespace std;
int n,m,k,q,le,ans;
int a[50005];
struct t1
{
    int l,r,va,lef;
}t[105][200005];
int read1()
{
	char cc=getchar();
	while(!(cc>=48&&cc<=57))
	{
		cc=getchar();
	}
    int s=cc-48;
	while(1)
	{
		cc=getchar();
		if(cc>=48&&cc<=57)
		{
			s=s*10+cc-48;
		}
		else
		{
			break;
		}
	}
	return s;
}
void build(int p,int l,int r)
{
    if(l==r)
    {
        for(int i=0;i<=m;i++)
        {
            t[i][p].l=l;
            t[i][p].r=r;
            t[i][p].va=min(m,i+a[l])/k;
            t[i][p].lef=min(m,i+a[l])%k;
        }
    }
    else
    {
        int mid=(l+r)>>1;
        build(p*2,l,mid);
        build(p*2+1,mid+1,r);
        for(int i=0;i<=m;i++)
        {
            t[i][p].l=l;
            t[i][p].r=r;
            t[i][p].va=t[i][p*2].va+t[t[i][p*2].lef][p*2+1].va;
            t[i][p].lef=t[t[i][p*2].lef][p*2+1].lef;
        }
    }
}
void change(int p,int c,int va)
{
    if(t[0][p].l==t[0][p].r)
    {
        a[c]+=va;
        for(int i=0;i<=m;i++)
        {
            t[i][p].va=min(m,i+a[c])/k;
            t[i][p].lef=min(m,i+a[c])%k;
        }
    }
    else
    {
        int mid=(t[0][p].l+t[0][p].r)>>1;
        if(c<=mid)
        {
            change(p*2,c,va);
        }
        else
        {
            change(p*2+1,c,va);
        }
        for(int i=0;i<=m;i++)
        {
            t[i][p].va=t[i][p*2].va+t[t[i][p*2].lef][p*2+1].va;
            t[i][p].lef=t[t[i][p*2].lef][p*2+1].lef;
        }
    }
}
void ask(int p,int l,int r)
{
    if(l<=t[0][p].l&&r>=t[0][p].r)
    {
        ans=ans+t[le][p].va;
        le=t[le][p].lef;
    }
    else
    {
        int mid=(t[0][p].l+t[0][p].r)>>1;
        if(l<=mid)
        {
            ask(p*2,l,r);
        }
        if(r>mid)
        {
            ask(p*2+1,l,r);
        }
    }
}
int main()
{
    cin>>n>>m>>k>>q;
    for(int i=1;i<=n;i++)
    {
        a[i]=read1();
    }
    build(1,1,n);
    for(int i=1;i<=q;i++)
    {
        int opt,u,v;
        opt=read1();
        u=read1();
        v=read1();
        if(opt==1)
        {
            change(1,u,v);
        }
        else
        {
            le=0;
            ans=0;
            ask(1,u,v);
            printf("%d\n",ans);
        }
    }
    return 0;
}

相關文章