题目
题目描述
Limak, a bear, isn’t good at handling queries. So, he asks you to do it.
We say that powers of 4242 (numbers 1,42,1764,…1,42,1764,… ) are bad. Other numbers are good.
You are given a sequence of nn good integers t_{1},t_{2},…,t_{n}t
1
,t
2
,…,t
n
. Your task is to handle qq queries of three types:
1 i — print t_{i}t
i
in a separate line.
2 a b x — for set t_{i}t
i
to xx . It’s guaranteed that xx is a good number.
3 a b x — for increase t_{i}t
i
by xx . After this repeat the process while at least one t_{i}t
i
is bad.
You can note that after each query all t_{i}t
i
are good.
输入格式
The first line of the input contains two integers nn and qq ( 1<=n,q<=1000001<=n,q<=100000 ) — the size of Limak’s sequence and the number of queries, respectively.
The second line of the input contains nn integers t_{1},t_{2},…,t_{n}t
1
,t
2
,…,t
n
( 2<=t_{i}<=10^{9}2<=t
i
<=10
9
) — initial elements of Limak’s sequence. All t_{i}t
i
are good.
Then, qq lines follow. The ii -th of them describes the ii -th query. The first number in the line is an integer type_{i}type
i
( 1<=type_{i}<=31<=type
i
<=3 ) — the type of the query. There is at least one query of the first type, so the output won’t be empty.
In queries of the second and the third type there is 1<=a<=b<=n1<=a<=b<=n .
In queries of the second type an integer xx ( 2<=x<=10^{9}2<=x<=10
9
) is guaranteed to be good.
In queries of the third type an integer xx ( 1<=x<=10^{9}1<=x<=10
9
) may be bad.
输出格式
For each query of the first type, print the answer in a separate line.
题意翻译
定义一个正整数是坏的,当且仅当它是 4242 的次幂,否则它是好的。
给定一个长度为 nn 的序列 a_ia
i
,保证初始时所有数都是好的。
有 qq 次操作,每次操作有三种可能:
1 i 查询 a_ia
i
。
2 l r x 将 a_{l\dots r}a
l…r
赋值为一个好的数 xx。
3 l r x 将 a_{l \dots r}a
l…r
都加上 xx,重复这一过程直到所有数都变好。
n,q \le 10^5n,q≤10
5
,a_i,x \le 10^9a
i
,x≤10
9
。
输入输出样例
输入 #1复制
6 12
40 1700 7 1672 4 1722
3 2 4 42
1 2
1 3
3 2 6 50
1 2
1 4
1 6
2 3 4 41
3 1 5 1
1 1
1 3
1 5
输出 #1复制
1742
49
1842
1814
1822
43
44
107
说明/提示
After a query 3 2 4 42 the sequence is 40,1742,49,1714,4,172240,1742,49,1714,4,1722 .
After a query 3 2 6 50 the sequence is 40,1842,149,1814,104,182240,1842,149,1814,104,1822 .
After a query 2 3 4 41 the sequence is 40,1842,41,41,104,182240,1842,41,41,104,1822 .
After a query 3 1 5 1 the sequence is 43,1845,44,44,107,182243,1845,44,44,107,1822 .
思路
用线段树维护即可,可以证明不会超时
代码
const int N = 1e5 + 7;
const ll inf = 1e18;
int n, q;
ll p[12] = {1}, a[N];
set<int> s;
struct T {
int l, r, o;
ll z;
pair<ll, int> x;
} t[N<<2];
int f(ll x) {
return lower_bound(p, p + 12, x) - p;
}
void upd(int p) {
t[p].x = min(t[ls].x, t[rs].x);
}
void build(int p, int l, int r) {
t[p].l = l, t[p].r = r;
if (l == r) return t[p].x = mp(::p[t[p].o=f(a[l])] - a[l], l), void();
build(ls, l, md), build(rs, md + 1, r), upd(p);
}
void spd(int p) {
t[ls].z = max(-inf, t[ls].z + t[p].z);
t[rs].z = max(-inf, t[rs].z + t[p].z);
t[ls].x.fi = min(inf, t[ls].x.fi - t[p].z);
t[rs].x.fi = min(inf, t[rs].x.fi - t[p].z);
t[p].z = 0;
}
ll ask(int p, int x) {
if (t[p].l == t[p].r) return ::p[t[p].o] - t[p].x.fi;
spd(p);
return ask(x <= md ? ls : rs, x);
}
void setx(int p, int o, ll x) {
if (t[p].l == t[p].r)
return t[p].x = mp(::p[t[p].o=f(x)] - x, t[p].l), void();
spd(p);
setx(o <= md ? ls : rs, o, x);
upd(p);
}
void add(int p, int l, int r, ll x) {
if (t[p].l >= l && t[p].r <= r)
return t[p].z += x, t[p].x.fi -= x, void();
spd(p);
if (l <= md) add(ls, l, r, x);
if (r > md) add(rs, l, r, x);
upd(p);
}
void work2(int l, int r, ll x) {
if (l != 1) setx(1, l - 1, ask(1, *s.lower_bound(l - 1))), s.insert(l - 1);
s.erase(s.lower_bound(l), s.upper_bound(r));
setx(1, r, x), s.insert(r);
if (l < r) add(1, l, r - 1, -inf);
}
void upd(int p, int x) {
if (t[p].l == t[p].r) {
ll k = ::p[t[p].o] - t[p].x.fi;
t[p].x = mp(::p[t[p].o=f(k)] - k, t[p].l);
return;
}
spd(p);
upd(x <= md ? ls : rs, x);
upd(p);
}
void work3(int l, int r, ll x) {
if (l != 1) setx(1, l - 1, ask(1, *s.lower_bound(l - 1))), s.insert(l - 1);
setx(1, r, ask(1, *s.lower_bound(r))), s.insert(r);
do {
add(1, l, r, x);
while (t[1].x.fi < 0) upd(1, t[1].x.se);
} while (!t[1].x.fi);
}
int main() {
for (int i = 1; i < 12; i++) p[i] = p[i-1] * 42;
rd(n), rd(q), rda(a, n);
for (int i = 1; i <= n; i++) s.insert(i);
build(1, 1, n);
for (int i = 1, o, x, l, r; i <= q; i++) {
rd(o);
switch (o) {
case 1 : rd(x), print(ask(1, *s.lower_bound(x))); break;
case 2 : rd(l), rd(r), rd(x), work2(l, r, x); break;
case 3 : rd(l), rd(r), rd(x), work3(l, r, x); break;
}
}
return 0;
}