ナマケモノの概要ラインXORの+アートラベル(ロス・バレーP2574)

アートの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;
}

公開された264元の記事 ウォン称賛46 ビュー10000 +

おすすめ

転載: blog.csdn.net/qq_44291254/article/details/105210323