時間限制: 1 s
空間限制: 256000 kb
題目等級 : 鑽石 diamond
題解給出n個數,要求做m次區間翻轉(如1 2 3 4變成4 3 2 1),求出最後的序列
輸入描述 input description
第一行乙個數n,下一行n個數表示原始序列,在下一行乙個數m表示m次翻轉,之後的m行每行兩個數l,r表示將區間[l,r]翻轉。
輸出描述 output description
一行n個數 , 表示最終序列。
樣例輸入 sample input
1 2 3 4
1 23 4
樣例輸出 sample output
2 1 4 3
資料範圍及提示 data size & hint
對於30%的資料滿足n<=100 , m <= 10000
對於100%的資料滿足n <= 150000 , m <= 150000
對於100%的資料滿足n為2的冪,且l = i * 2^j + 1 , r = (i + 1) * 2^j
分類標籤 tags 點此展開
線段樹樹結構
題解:
splay~~~
因為題目中l = i * 2^j + 1 , r = (i + 1) * 2^j的限制,所以給出的反轉區間必然是線段樹中乙個整塊,那麼我們可以利用這個性質,每次對於需要反轉的區間打反轉標記,對於線段樹中的每乙個節點記錄他的左右兒子,標記下放的時候,就交換左右兒子,查詢的時候<=mid就跳轉到左兒子,否則跳轉到右兒子。
這樣的話就可以直接用線段樹來搞,區間打標記然後交換左右兒子就可以了。
ac**:
跑過全網
#include#include#define lc k<<1
#define rc k<<1|1
using
namespace
std;
inline
const
intread()
while(ch>='
0'&&ch<='9')
return x*f;
}const
int m=2e5+10
;const
int n=m<<2
;int
ls[n],rs[n],rev[n],pos[n],a[m];
inline
void build(int k,int l,int
r)
int mid=l+r>>1
; ls[k]=lc;rs[k]=rc;
build(ls[k],l,mid);
build(rs[k],mid+1
,r);
}inline
void pushdown(int
k)inline
void change(int k,int l,int r,int x,int
y) pushdown(k);
int mid=l+r>>1
;
if(y<=mid) change(ls[k],l,mid,x,y);
else
if(x>mid) change(rs[k],mid+1
,r,x,y);
else change(ls[k],l,mid,x,mid),change(rs[k],mid+1,r,mid+1
,y);
}inline
int query(int k,int l,int r,int
p)int
main()
4975 區間翻轉
小q和tangjz正在乙個長度為n的序列a 1,a 2,a n上玩乙個有趣的關於區間翻轉的遊戲。小q和tangjz輪流行動 小q先手。每次行動方玩家需要選擇乙個長度為4x 2或4x 3的區間 l,r 1 l r n 其中x是該玩家自行選擇 的非負整數,然後將a l,a a a r翻轉,例如1 3 2...
codevs 3243 區間反轉(線段樹)
時間限制 1 s 空間限制 256000 kb 題目等級 鑽石 diamond 題解 檢視執行結果 給出n個數,要求做m次區間翻轉 如1 2 3 4變成4 3 2 1 求出最後的序列 輸入描述 input description 第一行乙個數n,下一行n個數表示原始序列,在下一行乙個數m表示m次翻轉...
bzoj 4975 區間翻轉
小q和tangjz正在乙個長度為n的序列a 1,a 2,a n上玩乙個有趣的關於區間翻轉的遊戲。小q和tangjz輪流行動,小q先手。每次行動方玩家需要選擇乙個長度為4x 2或4x 3的區間l,r,其中x是該玩家自行選擇的非負整數,然後將a l,a a a r翻轉,例如1 3 2 5 4翻轉會得到4...