アートのXOR
タイトル説明
AKN最初の質問、あまりにも多くの水は、彼が新しいゲームを遊んでいたので、最初の質問を書くことを気に。ゲームでは、彼は、法律では、次のこのゲームでダメージ計算は法律があることがわかりました
怪我の文字列は、長さの文字列のn文字のみ0と文字の1を含むでいます。最初の文字のこの文字列の規定は、インデックスが1から始まることを最初の文字です。
範囲[L、R]、この範囲の文字列内の損傷の損傷の数、所与の1
修正ダメージ値列、修正された方法は、1から0へのすべての元の文字0〜1、で[L、R]です。
AKNが痛いの瞬間のいくつかを知りたい、あなたは彼がダメージを見つけるのに役立ちます。
入力形式
入力の最初の行は整数で分離された2つの空間を有し、傷害の文字列は、長さnは、mおよび操作の数を表します。
第二の入力ラインは、傷害のストリングの代表長さN Sの文字列です。
第三に(M + 2)行それぞれ有する三スペースで区切られた整数OP、L、R。iモードや操作の範囲を代表して、ルールは次のとおりです。
OP = 0の場合には、区間内の損傷列[L、R] 0は1,1がゼロになるとなることを示しています。
OP = 1の場合は、そのクエリ[L、R]間隔損傷の文字列の文字数を示します。
出力フォーマット
各クエリ、出力線部1の整数を表すため。
この質問は理解して使用するように怠惰なラベルツリーラインを調べることです。
ここだけの復習です。
レイジーマークは、通常、変更ゾーンが使用されます。
レイジーマーク名は、示唆特に怠惰であるそれはあなたがそれを必要とする場合にのみ、それが表示されますです;。我々は、ゾーンに変更した場合、1つの変化し、爆発の後、複雑さ、明らかにされていない場合、次にラベルされた怠惰役割は、各セグメントに対して、反射、プラス遅延マーク、修正するかどうかをこの間隔をマーキング行った場合、そのサブセクションは、怠惰な子ノードをマークするように変更して転送されるべきである(子からですサブインターバルのノードが変更されました)。
この質問はないだけで有用なマーカー怠惰、怠け者もショーマークが競合作成することができ、操作のマークが再度操作を記念して、処理されていないです。
XORは特に適しているので、操作は、二回の動作の等価ではないので、各間隔XOR演算のための怠惰なマーク;:バックソリューションのこの質問に来ます
コード:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=200010;
const int M=2000100;
const LL mod=1e8-3;
int n,m;
string s;
struct Node{
int l,r,w,lt;
}tr[N*4];
void build(int l,int r,int k){
tr[k].l=l,tr[k].r=r;
if(l==r) return;
int d=(l+r)>>1;
build(l,d,ls);
build(d+1,r,rs);
}
void add(int p,int k){
if(tr[k].l==tr[k].r){
tr[k].w++;
return;
}
int d=(tr[k].l+tr[k].r)>>1;
if(p<=d) add(p,ls);
else add(p,rs);
tr[k].w=tr[ls].w+tr[rs].w;
}
void pd(int k){
tr[ls].lt^=1;
tr[rs].lt^=1;
tr[ls].w=tr[ls].r-tr[ls].l+1-tr[ls].w;
tr[rs].w=tr[rs].r-tr[rs].l+1-tr[rs].w;
tr[k].lt=0;
}
void update(int l,int r,int k){
if(tr[k].l>=l&&tr[k].r<=r){
tr[k].w=tr[k].r-tr[k].l+1-tr[k].w;
tr[k].lt^=1;
return;
}
if(tr[k].lt) pd(k);
int d=(tr[k].l+tr[k].r)>>1;
if(l<=d) update(l,r,ls);
if(r>d) update(l,r,rs);
tr[k].w=tr[ls].w+tr[rs].w;
}
int query(int l,int r,int k){
if(tr[k].l>=l&&tr[k].r<=r) return tr[k].w;
if(tr[k].lt) pd(k);
int sum=0;
int d=(tr[k].l+tr[k].r)>>1;
if(l<=d) sum+=query(l,r,ls);
if(r>d) sum+=query(l,r,rs);
return sum;
}
int main(){
cin>>n>>m;
cin>>s;
build(1,n,1);
for(int i=0;i<n;i++) if(s[i]=='1') add(i+1,1);
while(m--){
int p,l,r;
scanf("%d%d%d",&p,&l,&r);
if(p==0) update(l,r,1);
else printf("%d\n",query(l,r,1));
}
return 0;
}