玄学求调
查看原帖
玄学求调
1076971
anke2017楼主2024/9/13 20:13

在我们OJ的树状数组模板中,卡区改区查空间至32MB,并且 n106n \le 10^6

但是,以下代码理论上的占用空间为 30MB 左右,还是MLE 43MB。求原因或调整
注:以下代码本题可过

#include<iostream>
#include<cstdio>

using namespace std;

bool ttt;

inline char nc()
{
    static char buf[1000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}

void read(long long& x)
{
    char a=nc();
    bool flag=0;
    while(!isdigit(a)){if(a=='-')flag=1;a=nc();}
    x=0;
    while(isdigit(a))
    {
    	x=(x<<1)+(x<<3);
        x+=(a-48);
        a=nc();
    }
    if(flag) x=-x;
}

void read(int& x)
{
    char a=nc();
    bool flag=0;
    while(!isdigit(a)){if(a=='-')flag=1;a=nc();}
    x=0;
    while(isdigit(a))
    {
    	x=(x<<1)+(x<<3);
        x+=(a-48);
        a=nc();
    }
    if(flag) x=-x;
}

inline void out(long long x)
{
    if(x==0) {putc('0',stdout);return;}
    if(x<0)
    {
        putc('-',stdout);
        x=-x;
    }
    int ans=1;
    static short n[20]={0};
    while(x)
    {
        n[ans]=x%10;
        x/=10;
        ans++;
    }
    for(int i=ans-1;i>=1;i--)
    {
        putc((n[i]+48),stdout);
    }
    putc('\n',stdout);
}

const int maxn=1e6+10;

struct seg_node
{
	long long num;
	long long lazy;
	int l;
};

struct segment_tree
{
	long long num[maxn];//8MB
	seg_node nodes[maxn];//20MB
	int cnt=1;
	inline void push_down(int now,int l,int r)
	{
		long long t=nodes[now].lazy;
		if(l+2<r){
            int mid=(l+r)>>1;
			nodes[nodes[now].l].lazy+=t;
			nodes[nodes[now].l+1].lazy+=t;
            nodes[nodes[now].l].num+=(mid-l+1)*t;
            nodes[nodes[now].l+1].num+=(r-mid)*t;
			nodes[now].lazy=0;
			return;
		}
		if(l+1==r){num[l]+=t;num[r]+=t;nodes[now].lazy=0;return;}
		if(l+2==r){nodes[nodes[now].l].lazy+=t;nodes[nodes[now].l].num+=(t<<1);num[r]+=t;nodes[now].lazy=0;return;}
	}
	long long build(int now,int l,int r)
	{
        if(l==r)return num[l];
		if(l+1==r)return nodes[now].num=num[l]+num[r];
		nodes[now].l=++cnt;
		if(l+2==r)return nodes[now].num=build(cnt,l,l+1)+num[r];
		int mid=(l+r)>>1;
		++cnt;
		return 
          nodes[now].num=build(nodes[now].l,l,mid)+build(nodes[now].l+1,mid+1,r);
	}
	inline int max1(int l,int r){return l<r?r:l;}
	inline int min1(int l,int r){return l<r?l:r;}
	void change(int now,int l,int r,int ql,int qr,long long add)
	{
		if(l==r){num[l]+=add;return;}
		if(ql<=l&&r<=qr){nodes[now].lazy+=add;nodes[now].num+=(r-l+1)*(long long)add;return;}
		push_down(now,l,r);
		int mid=(l+r)>>1;
		if(ql<=mid)change(nodes[now].l,l,mid,ql,qr,add);
		if(mid<qr)change(nodes[now].l+1,mid+1,r,ql,qr,add);
		nodes[now].num+=(min1(qr,r)-max1(ql,l)+1)*(long long)add;
        //cout<<now<<' '<<l<<' '<<r<<' '<<nodes[now].num<<'\n';
	}
	long long query(int now,int l,int r,int ql,long long qr)
	{
		if(l==r)return num[l];
		if(ql<=l&&r<=qr)return nodes[now].num;
		push_down(now,l,r);
		int mid=(l+r)>>1;
		long long ans=0;
		if(ql<=mid)ans=query(nodes[now].l,l,mid,ql,qr);
		if(mid<qr)ans+=query(nodes[now].l+1,mid+1,r,ql,qr);
		return ans;
	}
}tree;
bool ttt2;
int main()
{
    //cout<<(&ttt-&ttt2)<<'\n';
    int a,b;read(a),read(b);
    for(int i=1;i<=a;i++)
    {
        read(tree.num[i]);
    }
    tree.build(1,1,a);
    for(int i=1,t1,t2,t3,t4;i<=b;i++)
    {
        read(t1),read(t2),read(t3);
        if(t1==1)
        {
            read(t4);
            tree.change(1,1,a,t2,t3,t4);
        }
        else
        {
            out(tree.query(1,1,a,t2,t3));
        }
    }
    return 0;
}
2024/9/13 20:13
加载中...