线段树求助!思路是区间异或
查看原帖
线段树求助!思路是区间异或
905233
Rebirth_Yun楼主2023/8/2 11:05

代码如下

#include<bits/stdc++.h>
using namespace std;
const int maxn =2*10e5+10;
long long a[maxn]{0},w[maxn*4];
long long lzy[maxn*4];

void pushup(const int u)//维护
{
    w[u] = w[u*2] + w[u*2+1]; //w[u] 是区间 u*2是左子树 u*2+1右子树
}

bool inRange(int L,int R,int l,int r)
{
    return(l<=L)&&(R<=r);
}

bool outofRange(int L,int R,int l,int r)
{
    return (L > r)||(R < l);
}

void maketag(int u, int len)
{
    w[u]=len-w[u];
    lzy[u]^=1;
}

void pushdown(int u,int l,int r)
{
    int m = (l+r)/2;
    maketag(u*2, m-l+1);//左子树加lzy[u]
    maketag(u*2+1, r-m);//右子树加lzy[u]
    lzy[u]=0;
}

long long query(int u,int L,int R,int l,int r)//区间查询
{
    if(inRange(L,R,l,r))//如果完全包含返回区间值
    {
        return w[u];
    }
    else if(!outofRange(L,R,l,r))//若相交,递归处理
        {
            int m = (L + R)/2;
            pushdown(u,L,R);//查询的时候也需要将节点标记下放
            return query(u*2, L, m, l, r)+query(u*2+1, m+1, R, l, r);
        }
        else return 0;
}

void update(int u,int L,int R,int l,int r)
{
    if(inRange(L,R,l,r))
    {
        maketag(u,R-L+1);//完全包含打包标记
    }
    else if(!outofRange(L,R,l,r))
        {
            int M =(L+R)/2;
            pushdown(u,L,R);//先将当前节点标记下穿 然后修改下面的节点
            update(u*2,L,M,l,r);
            update(u*2+1,M+1,R,l,r);
            pushup(u);
        }
}

int main()
{
    ::ios_base::sync_with_stdio(false);
    int n,m;
    cin >> n >> m;
    for(int t=1;t<=m;t++)
    {
        int op,x,y;
        long long k;
        cin >> op;
        if(op==0)
        {
            cin >> x >> y ;
            update(1,1,n,x,y);
        }
        else
        {
            cin >> x >> y;
            cout << query(1,1,n,x,y) << '\n';
        }
    }
    return 0;
}

我想的是把lazy ^1然后更新w中1的个数T T 不知道哪一步错了

2023/8/2 11:05
加载中...