社区讨论

助我逃离幽蓝边界!

P11071「QMSOI R1」 Distorted Fate参与者 2已保存回复 3

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@mlolndcw
此快照首次捕获于
2026/02/16 11:13
3 天前
此快照最后确认于
2026/02/16 23:56
3 天前
查看原帖
求调代码。
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
const int mod=1<<30;
bool ad[800010][30],o[800010][30],tag[800010][30];//与和或 
inline void upd(int root,int k){
    if(ad[root][k]==o[root][k]) ad[root][k]^=1,o[root][k]^=1;
}
inline void pushdown(int root,int k){
    if(!tag[root][k]) return;
    upd(root*2,k),upd(root*2+1,k);
    tag[root*2][k]^=1,tag[root*2+1][k]^=1;
}
inline void update(int l,int r,int k,int x=1,int y=n+1,int root=1){
    if(l<=x && y<=r){
        upd(root,k),tag[root][k]^=1;
        return;
    }
    int mid=x+y>>1;
    pushdown(root,k);
    if(l<=mid) update(l,r,k,x,mid,root*2);
    if(mid<r) update(l,r,k,mid+1,y,root*2+1);
ad[root][k]=ad[root*2][k]&ad[root*2+1][k],o[root][k]=o[root*2][k]|o[root*2+1][k];
}
inline int find(int root,int k,int l,int r){
    if(l==r) return l;
    int mid=l+r>>1;
    pushdown(root,k);
    if(o[root*2][k]) return find(root*2,k,l,mid);
    else return find(root*2+1,k,mid+1,r);
}
inline int ask(int l,int r,int k,int x=1,int y=n+1,int root=1){
    if(l<=x && y<=r){
        if(o[root][k]) return find(root,k,x,y);
        else return -1;
    }
    int mid=x+y>>1;
    pushdown(root,k);
    if(l<=mid){
        int t=ask(l,r,k,x,mid,root*2);
        if(t!=-1) return t;
    }
    if(mid<r){
        int t=ask(l,r,k,mid+1,y,root*2+1);
        if(t!=-1) return t;
    }
    return -1;
}
signed main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        for(int p=0;p<30;p++) if(x&(1<<p)) update(i,i,p);
    }
    while(m--){
        int opt;
        cin>>opt;
        if(opt==1){
            int l,r,x;
            cin>>l>>r>>x;
            for(int p=0;p<30;p++) if(x&(1<<p)) update(l,r,p);
        }
        if(opt==2){
            int l,r;
            cin>>l>>r;
            long long ans=0;
            for(int p=0;p<30;p++){
                int t=ask(l,r,p);
                if(t!=-1) ans=(ans+(1ll<<p)*(r-min(r+1,t)+1))%mod;
            }
            cout<<ans<<"\n";
        }
    }
    return 0;
}

回复

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

正在加载回复...