Range Update Query

数列  = { ,...,} に対し、次の2つの操作を行うプログラムを作成せよ。

  • : ,..., をに変更する。
  • :  の値を出力する。

ただし、 (,...,)は、2-1で初期化されているものとする。

入力

 


:

1行目にの要素数, クエリの数が与えられる。続く行に 番目のクエリ  が与えられる。 は以下のいずれかの形式で与えられる。

0   

または

1 

各クエリの最初の数字は、クエリの種類を示し、'0'が、'1'が を表す。

出力

各クエリについて、値を1行に出力せよ。

制約

入力例 1

3 5
0 0 1 1
0 1 2 3
0 2 2 2
1 0
1 1

出力例 1

1
3

入力例 2

1 3
1 0
0 0 0 5
1 0

出力例 2

2147483647
5

 
 

区间修改,单点查询,线段树+tag标记。压了压常数,继续打榜。

 #include <cstdio>
#include <cstdlib>
#include <cstring> #define siz 10000000 char buf[siz], *bit = buf; inline int nextInt(void) {
register int ret = ;
register int neg = false; for (; *bit < ''; ++bit)
if (*bit == '-')neg ^= true; for (; *bit >= ''; ++bit)
ret = ret * + *bit - ''; return neg ? -ret : ret;
} #define inf 2147483647 int n, m; int tag[]; int find(int t, int l, int r, int p) {
if (~tag[t])
return tag[t];
int mid = (l + r) >> ;
if (p <= mid)
return find(t << , l, mid, p);
else
return find(t << | , mid + , r, p);
} void update(int t, int l, int r, int x, int y, int k) {
if (l == x && r == y)
tag[t] = k;
else {
int mid = (l + r) >> ;
if (~tag[t])
tag[t << ] = tag[t << | ] = tag[t], tag[t] = -;
if (y <= mid)
update(t << , l, mid, x, y, k);
else if (x > mid)
update(t << | , mid + , r, x, y, k);
else {
update(t << , l, mid, x, mid, k);
update(t << | , mid + , r, mid + , y, k);
}
}
} signed main(void) {
fread(buf, , siz, stdin); n = nextInt();
m = nextInt(); for (int i = ; i < (n << ); ++i)
tag[i] = inf; for (int i = ; i <= m; ++i) {
int c = nextInt();
if (c) // find(x)
printf("%d\n", find(, , n, nextInt() + ));
else {
int x = nextInt();
int y = nextInt();
int k = nextInt();
update(, , n, x + , y + , k);
}
} //system("pause");
}

@Author: YouSiki

05-11 13:11