题意:带修改地维护区间异或和
思路:带修改莫队(注意分块大小为 0.66666n)
#include <bits/stdc++.h>
using namespace std;
typedef int lint;
typedef long long LL;
const lint maxn = 1000005;
lint a[maxn],pos[maxn],sum[maxn];
LL ans[maxn];
lint block;
struct query{lint l,r,k,id;query( lint ll = 0,lint rr = 0,lint kk = 0,lint idid = 0 ){l = ll; r = rr;k = kk;id = idid;}bool operator < ( const query & b )const{if( l/block == b.l/block ){if( r/block == b.r/block ){return k < b.k;}return r < b.r ;}return l < b.l;}
};
vector<query> ve;
LL cnt[maxn],ccnt;
void init(lint n){block = floor(pow(n,0.6666666));memset( cnt,0,sizeof(cnt) );ccnt = 0;
}
void update( lint v,lint f ){if( f == 1 ){ccnt += cnt[v];cnt[v]++;}else{cnt[v]--;ccnt -= cnt[v];}
}
void up( lint L,lint R,lint tim ){lint p = pos[tim];if( p >= L && p <= R ){cnt[ sum[p] ]--;ccnt -= cnt[ sum[p] ];swap( a[p],a[p+1] );sum[p] = sum[p-1]^a[p];ccnt += cnt[ sum[p] ];cnt[ sum[p] ]++;}else{swap( a[p],a[p+1] );sum[p] = sum[p-1]^a[p];}
}
void solve(){lint L = 0,R = -1,TIM = 0;for( lint i = 0;i < ve.size();i++ ){lint tim = ve[i].k;lint l = ve[i].l;lint r = ve[i].r;while( TIM > tim ) {up( L,R,TIM-- );}while( TIM < tim ){up( L,R,++TIM );}while( R < r ) update( sum[++R],1 );while( l < L ) update( sum[--L],1 );while( R > r ) update( sum[R--],-1 );while( l > L ) update( sum[L++],-1 );ans[ ve[i].id ] = (LL)(r - l)*(r-l+1)/2-ccnt;}
}
int main() {lint n,m;while( 2 == scanf("%d%d",&n,&m) ){init(n);ve.clear();lint id = 0,tim = 0;for( lint i = 1;i <= n;i++ ) {scanf("%d",&a[i]);sum[i] = sum[i-1]^a[i];}for( lint i = 1;i <= m;i++ ){lint op;scanf("%d",&op);if( op == 1 ){id++;lint l,r;scanf("%d%d",&l,&r);l--;//cout << id << endl;ve.push_back( query( l,r,tim,id ) );}else{lint p;scanf("%d",&p);tim++;pos[tim] = p;}}sort( ve.begin(),ve.end() );solve();for( lint i = 1;i <= id;i++ ){printf("%lld\n",ans[i]);}}return 0;
}