社区讨论

萌新刚学OI,求助大佬

学术版参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi7xzu4g
此快照首次捕获于
2025/11/21 05:27
4 个月前
此快照最后确认于
2025/11/21 05:27
4 个月前
查看原帖

【模板】线段树

时间限制 500ms 空间限制 128MB

题目背景

CPP
这是一道模板题。

题目描述

CPP

第一个操作:对区间[x,y]中的每一个数都开根(向下取整)。

第二个操作:给第x个数加上y

第三个操作:求区间[x,y]中每一个数的和

第四个操作:求区间[x,y]中的最大值

第五个操作:求区间[x,y]中的最小值

输入输出格式

CPP
输入格式:

第一行输入两个正整数n和m,表示数列有n个数,有m个操作。

接下来一行有n个正整数表示数列的初始值。

最后m行每行三个数z,x,y 对应第z个操作

输出格式:

对应所有的z=3/4/5的询问操作,输出询问信息

输入输出样例

CPP
输入样例: 

3 3
1 1 1
1 1 2
3 1 3
4 1 2

输出样例: 

3
1

数据范围

CPP
n,m<=10^5,输入的数均为正整数且<=10^9

我的代码

CPP
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

#define LL long long
#define ts tr[k].sum
#define tx tr[k].maxt
#define tn tr[k].mint
#define ts2 tr[k<<1].sum
#define tx2 tr[k<<1].maxt
#define tn2 tr[k<<1].mint
#define ts3 tr[k<<1|1].sum
#define tx3 tr[k<<1|1].maxt
#define tn3 tr[k<<1|1].mint
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define mid ((l+r)>>1)

const int N=1e5+5;
LL n,m,a[N],res;
struct TREE{LL maxt,mint,sum;}tr[N<<2];

inline void build(int l,int r,int k)
{
    if(l==r)
    {
        ts=tx=a[l];
        return;
    }
    build(l,mid,k<<1);
    build(mid+1,r,k<<1|1);
    ts=ts2+ts3; tx=max(tx2,tx3); tn=min(tn2,tn3);
    return;
}

inline void add(int l,int r,int v,int x,int k)
{
    if(r<x||l>x) return;
    if(l==r&&l==x)
    {
        ts+=v;
        tx+=v;
        tn+=v;
        return;
    }
    add(l,mid,v,x,k<<1);
    add(mid+1,r,v,x,k<<1|1);
    ts=ts2+ts3; tx=max(tx2,tx3); tn=min(tn2,tn3);
    return;
}
inline void sqr(int l,int r,int ql,int qr,int k)
{
    if(tx<=1) return;
    if(l==r)
    {
        ts=sqrt(ts);
        tx=sqrt(tx);
        return;
    }
    if(ql<=mid) sqr(l,mid,ql,qr,k<<1);
    if(mid<qr) sqr(mid+1,r,ql,qr,k<<1|1);
    ts=ts2+ts3; tx=max(tx2,tx3); tn=min(tn2,tn3);
    return;
}

inline LL query(int l,int r,int ql,int qr,int k,int flag)
{
    if(flag==3)
    {
    	if(l>=ql&&r<=qr) return ts;
    	if(ql<=mid) res+=query(l,mid,ql,qr,k<<1,3);
        if(qr>mid) res+=query(mid+1,r,ql,qr,k<<1|1,3);
    }
    if(flag==4)
    {
    	if(l>=ql&&r<=qr) return tx;
    	if(ql<=mid) res=max(res,query(l,mid,ql,qr,k<<1,4));
        if(qr>mid) res=max(res,query(mid+1,r,ql,qr,k<<1|1,4));
    }
    if(flag==5)
    {
    	if(l>=ql&&r<=qr) return ts;
    	if(ql<=mid) res=min(res,query(l,mid,ql,qr,k<<1,5));
        if(qr>mid) res=min(res,query(mid+1,r,ql,qr,k<<1|1,5));
    }
    return res;
}

int main()
{
    int f,x,y,k;
    scanf("%lld%lld",&n,&m);
    for(register int i=1;i<=n;i++) scanf("%lld",&a[i]);
    build(1,n,1);
    for(register int i=1;i<=m;i++)
    {
        scanf("%d",&f);
        if(f==1)
        {
            scanf("%d%d",&x,&y);
            if(x>y) swap(x,y);
            sqr(1,n,x,y,1);
        }
        else if(f==2)
        {
            scanf("%d%d",&x,&y);
            if(x>y) swap(x,y);
            add(1,n,y,x,1);
        }
        else
        {
        	scanf("%d%d",&x,&y);
        	if(x>y) swap(x,y);
        	if(f==3) res=0;
        	if(f==4) res=-1;
        	if(f==5) res=2147483647;
        	LL ans=query(1,n,x,y,1,f);
        	printf("%lld\n",ans);
        }
    }
    return 0;
}

TLE+WA 求大佬查错,万分感谢

回复

2 条回复,欢迎继续交流。

正在加载回复...