为什么把define 里面的(l+r)/2改为l+r>>1为出现玄学错误

P3372 【模板】线段树 1

hwwqy @ 2023-08-24 20:06:22

#include<bits/stdc++.h>
#define int long long
#define ls x<<1
#define rs x<<1|1
#define mid (l+r)/2
#define MAXN 10010
using namespace std;
int n,m;
int sum[MAXN<<2],tag[MAXN<<2],a[MAXN];
void init()
{
    memset(sum,0,sizeof(sum));
    memset(a,0,sizeof(a));
    memset(tag,0,sizeof(tag));
}
void update(int x,int l,int r)
{
    if(l-r)
    {
        sum[x]=sum[ls]+sum[rs];
    }       
}
void pushdown(int x,int l,int r)
{
    if(tag[x]==0)return;
    sum[ls]+=tag[x]*(mid-l+1);
    sum[rs]+=tag[x]*(r-mid);
    tag[ls]+=tag[x];
    tag[rs]+=tag[x];
    tag[x]=0;
    return;
}
void build(int x,int l,int r)
{
    //cout<<x<<" "<<l<<" "<<r<<" "<<(mid)<<endl;
    if(l==r)
    {
        sum[x]=a[l];
        return;
    }
    build(ls,l,mid);
    build(rs,mid+1,r);
    update(x,l,r);
    return;
}

void add(int x,int l,int r,int ql,int qr,int k)
{
    if(ql<=l&&r<=qr)
    {
        sum[x]+=(r-l+1)*k;
        tag[x]+=k;
        return;
    }
    pushdown(x,l,r);
    int res=0;
    if(mid>=ql)add(ls,l,mid,ql,qr,k);
    if(mid<qr)add(rs,mid+1,r,ql,qr,k);
    update(x,l,r);
}
int query(int x,int l,int r,int ql,int qr)
{
    //cout<<x<<" "<<l<<" "<<r<<endl;
    if(ql<=l&&r<=qr)
    {
        return  sum[x];
    }
    pushdown(x,l,r);
    int res=0;
    if(mid>=ql)res+=query(ls,l,mid,ql,qr);
    if(mid<qr)res+=query(rs,mid+1,r,ql,qr);
    return res;
}
inline int read()
{
    int f=1,x=0;
    char c=getchar();
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    while(c=='-') f=-f,c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return f*x;
}
signed main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    cout<<sum[1]<<endl;
    while(m--)
    {
        int type=read(),x=read(),y=read(),k;
        if(type==1) k=read(),add(1,1,n,x,y,k);
        else printf("%lld\n",query(1,1,n,x,y));
    }
    return 0;
}

by bamboo12345 @ 2023-08-24 20:08:15

@hwwqy 你多打个括号估计就可以了

(l+r>>1)

by _•́へ•́╬_ @ 2023-08-24 20:08:42

((l)+(r)>>1)


by hwwqy @ 2023-08-24 20:12:53

@bamboo123 确实,可为什么会这样呢


by bamboo12345 @ 2023-08-24 20:14:17

@hwwqy 就是宏定义他是直接替换不是定义了个函数,要多加括号保证运算顺序,位移运算优先级不高于加减


by vanishingloser @ 2023-08-24 20:19:18

((l+r)>>1)

by wzhm54nr @ 2023-09-04 14:47:46

打括号就可以了

(l+r>>1)

<< 是位运算,优先级比较低,而宏只负责替换,不计算,所以有可能其他的先进行了运算 比如:

r-mid

会变成

r-l+r>>1

此时先算r-l+r


|