g. 小 w 開關燈 [ problem 4467
] [ discussion ]
description
晚上到家小 w 通過開關燈來保持自己神經的興奮以便清醒地理筆記。n
'>n(2≤
n≤100,
000'>2≤n≤100,000
)盞燈被連續的編號為 1…n
'>1…n
。剛回到家的時候,所有的燈都是關閉的。
小w 通過 n
'>
n個按鈕來控制燈的開關, 按第 i
'>i
個按鈕可以改變第 i
'>i
盞燈的狀態。
小w 發出 m
'>m(1≤
m≤100,
000'>1≤m≤100,000
)條指令,每個指令都是兩個整數中的乙個(0 或 1)。
第1 種指令(用 0 表示)包含兩個數字 s
i'>si
si 和 e
i'>ei(1≤
si≤e
i≤n'>1≤si≤ei≤n
),它們表示起始開關和終止開關。小 w 需要把從 s
i'>si
到 ei
'>ei
之間的按鈕都按一次,就可以完成這個指令。
第2 種指令(用 1 表示)同樣包含兩個數字 s
i'>si
和 ei
'>ei(1≤
si≤e
i≤n'>1≤si≤ei≤n
),不過這種指令是詢問從 s
i'>si
到 ei
'>ei
之間的燈有多少是亮著的。
請你幫助小 w 得到正確的答案。
input
第1 行: 用空格隔開的兩個整數 n
'>
n 和 m
'>
m。 第2..m+1
'>m+1
行: 每行表示乙個操作, 有三個用空格分開的整數: 指令號, s
i'>si
和 ei
'>ei
。 output
對於每一次詢問, 輸出一行表示詢問的結果。
samples
input copy
4 5output0 1 2
0 2 4
1 2 3
0 2 4
1 1 4
1hint2
【樣例解釋】
一共有 4 盞燈, 5 個指令。 下面是執行的情況:
1 2 3 4
init: o o o o o = 關 * = 開
0 1 2 -> * * o o 改變燈 1 和 2 的狀態
0 2 4 -> * o * *
1 2 3 -> 1 輸出在 2..3 的範圍內有多少燈是亮的
0 2 4 -> * * o o 改變燈 2 ,3 和 4 的狀態
1 1 4 -> 2 輸出在 1..4 的範圍內有多少燈是亮的
【資料規模】
source
石光中學 2018泉州集訓提高組day4
這個題一看就是要用線段樹做
主要是要知道乙個知識 t[p].s=t[p].r-t[p].l+1-t[p].s;(就是區間長度為5,有兩個2,t[p].s=2,如果反轉的話,t[p].s=5-2=3)
這個就是區間變化之後怎麼區間和
然後在弄乙個區間懶惰標記判斷要不要下傳標記,就是區間是不是要變換
#pragma gcc optimize(1)一開始wa了好幾遍是這樣寫的,就是沒有異或1,而是變化一次就把他變成一#pragma gcc optimize(2)
#pragma gcc optimize(3,"ofast","inline")#include
using
namespace
std;
typedef
long
long
ll;template
void read(tp &x)
if(ch=='-'
)else fh=1
;
while(ch>='
0'&&ch<='9'
) x*=fh;
}inline
char
read1()
const
int maxn=5e6+100
; struct
nodet[maxn];
void build(int p,int l,int
r)
int mid=(l+r)/2
; build(
2*p,l,mid);
build(
2*p+1,mid+1
,r);
} void push(int
p) }
void update(int p,int l,int
r)
if(t[p].lazy) push(p);
int mid=(t[p].l+t[p].r)/2
;
if(l<=mid)
if(r>mid)
t[p].s=t[2*p].s+t[2*p+1
].s;
} int query(int p,int l,int
r)
int ans=0
;
if(t[p].lazy) push(p);
int mid=(t[p].l+t[p].r)/2
;
if(l<=mid)
if(r>mid)
return
ans;
}int
n,m;
intmain()
else
if(op==1
) }
}
void push(int這樣有乙個問題,就是p) }
void update(int p,int l,int
r)
![](https://pic.w3help.cc/89a/3917117a4a2006d783e1b92a7ec58.jpeg)
本來該沒有變化的,就是如果用異或的話詢問兩次的話,就變成0了,就不會出現上面的情況了
#pragma gcc optimize(1)#pragma gcc optimize(2)
#pragma gcc optimize(3,"ofast","inline")#include
using
namespace
std;
typedef
long
long
ll;template
void read(tp &x)
if(ch=='-'
)else fh=1
;
while(ch>='
0'&&ch<='9'
) x*=fh;
}inline
char
read1()
const
int maxn=5e6+100
; struct
nodet[maxn];
void build(int p,int l,int
r)
int mid=(l+r)/2
; build(
2*p,l,mid);
build(
2*p+1,mid+1
,r);
} void push(int
p) }
void update(int p,int l,int
r)
if(t[p].lazy) push(p);
int mid=(t[p].l+t[p].r)/2
;
if(l<=mid)
if(r>mid)
t[p].s=t[2*p].s+t[2*p+1
].s;
} int query(int p,int l,int
r)
int ans=0
;
if(t[p].lazy) push(p);
int mid=(t[p].l+t[p].r)/2
;
if(l<=mid)
if(r>mid)
return
ans;
}int
n,m;
intmain()
else
if(op==1
) }
}
維護序列(線段樹維護區間乘 區間加)
給定乙個長度為n的原序列和模數mod,m個操作,a,b 區間乘c,a,b 區間加c,統計 a,b 的區間和。思路 線段樹維護的還是區間和,但是這裡我們需要用到兩個懶標記,乙個記錄加法,乙個記錄乘法,乘法懶標記下傳之後要重置為1而不是0。對於乙個乘法操作,他影響的是區間和還有這個區間的加法標記 乘法標...
線段樹 離散區間,單點維護區間
這道題當時用線段樹搞不行,用主席樹搞,也不行。當場自閉。其實當時想到離散,但是沒想到用單點維護線段樹的區間。你這樣想,無非就是2e6次詢問,最多1 e9被分成最多2e6區間,我們要求的位置,一定在這2e6點的右邊第乙個。那麼把這個點,以及這個點x以及x 1的點儲存下來。維護的時候,線段樹初始化所有的...
線段樹 離散區間,單點維護區間
這道題當時用線段樹搞不行,用主席樹搞,也不行。當場自閉。其實當時想到離散,但是沒想到用單點維護線段樹的區間。你這樣想,無非就是2e6次詢問,最多1 e9被分成最多2e6區間,我們要求的位置,一定在這2e6點的右邊第乙個。那麼把這個點,以及這個點x以及x 1的點儲存下來。維護的時候,線段樹初始化所有的...