線段樹上二分搜與經典題
如果你認為他只能做到單點修改,區間詢問,那麼就太少了!
Last updated
如果你認為他只能做到單點修改,區間詢問,那麼就太少了!
Last updated
int find(int x, int idx, int l, int r){
if(l==r) return l; //找到了就回傳
int m = (l+r)/2;
//往兩邊找,如果左邊的最大值>=x,往左繼續找
//否則往右找
if(tr[idx*2] >= x) return find(x, idx*2, l, m);
else return find(x, idx*2+1, m+1, r);
}#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const int MAXN = 1e5+5;
ll tr[MAXN*4], arr[MAXN];
ll combine(ll a, ll b){
return a+b;
}
void build(int idx, int l, int r){
if(l==r){
tr[idx] = arr[l];
}else{
int m = (l+r)/2;
build(idx*2,l,m);
build(idx*2+1,m+1,r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
}
void update(int pos, int idx, int l, int r){
if(l==r){
tr[idx] ^= 1;
return;
}
int m = (l+r)/2;
if(pos <= m) update(pos, idx*2, l, m);
else update(pos, idx*2+1, m+1, r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
ll query(int ql, int qr, int idx, int l, int r){
if(ql <= l && r <= qr){
return tr[idx];
}
int m = (l+r)/2;
if(ql > m){
return query(ql, qr, idx*2+1, m+1, r);
}
if(qr <= m){
return query(ql, qr, idx*2, l, m);
}
return combine(query(ql, qr, idx*2, l, m), query(ql, qr, idx*2+1, m+1, r));
}
int find(int x, int idx, int l, int r){
if(l==r) return l;
int m = (l+r)/2;
if(tr[idx*2] >= x) return find(x, idx*2, l, m);
else return find(x-tr[idx*2], idx*2+1, m+1, r);
}
signed main(){
fastio
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i++){
cin >> arr[i];
}
build(1, 0, n-1);
for(int i = 0;i < m;i++){
int op;
cin >> op;
if(op==1){
int i;
cin >> i;
update(i, 1, 0, n-1);
}else{
int k;
cin >> k;
k++;
cout << find(k, 1, 0, n-1) << "\n";
}
}
}#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const int MAXN = 1e5+5;
ll tr[MAXN*4], arr[MAXN];
ll combine(ll a, ll b){
return max(a,b);
}
void build(int idx, int l, int r){
if(l==r){
tr[idx] = arr[l];
}else{
int m = (l+r)/2;
build(idx*2,l,m);
build(idx*2+1,m+1,r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
}
void update(int pos, int val, int idx, int l, int r){
if(l==r){
tr[idx] = val;
return;
}
int m = (l+r)/2;
if(pos <= m) update(pos, val, idx*2, l, m);
else update(pos, val, idx*2+1, m+1, r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
ll query(int ql, int qr, int idx, int l, int r){
if(ql <= l && r <= qr){
return tr[idx];
}
int m = (l+r)/2;
if(ql > m){
return query(ql, qr, idx*2+1, m+1, r);
}
if(qr <= m){
return query(ql, qr, idx*2, l, m);
}
return combine(query(ql, qr, idx*2, l, m), query(ql, qr, idx*2+1, m+1, r));
}
int find(int x, int idx, int l, int r){
if(tr[idx] < x) return -1;
if(l==r) return l;
int m = (l+r)/2;
if(tr[idx*2] >= x) return find(x, idx*2, l, m);
else return find(x, idx*2+1, m+1, r);
}
signed main(){
fastio
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i++){
cin >> arr[i];
}
build(1, 0, n-1);
for(int i = 0;i < m;i++){
int op;
cin >> op;
if(op==1){
int i, v;
cin >> i >> v;
update(i, v, 1, 0, n-1);
}else{
int x;
cin >> x;
cout << find(x, 1, 0, n-1) << "\n";
}
}
}#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const int MAXN = 1e5+5;
ll tr[MAXN*4], arr[MAXN];
ll combine(ll a, ll b){
return max(a,b);
}
void build(int idx, int l, int r){
if(l==r){
tr[idx] = arr[l];
}else{
int m = (l+r)/2;
build(idx*2,l,m);
build(idx*2+1,m+1,r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
}
void update(int pos, int val, int idx, int l, int r){
if(l==r){
tr[idx] = val;
return;
}
int m = (l+r)/2;
if(pos <= m) update(pos, val, idx*2, l, m);
else update(pos, val, idx*2+1, m+1, r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
ll query(int ql, int qr, int idx, int l, int r){
if(ql <= l && r <= qr){
return tr[idx];
}
int m = (l+r)/2;
if(ql > m){
return query(ql, qr, idx*2+1, m+1, r);
}
if(qr <= m){
return query(ql, qr, idx*2, l, m);
}
return combine(query(ql, qr, idx*2, l, m), query(ql, qr, idx*2+1, m+1, r));
}
int pos = 1e9;
void find(int ql, int x, int idx, int l, int r){
if(tr[idx] < x) return;
if(l==r){
pos = l;
return;
}
int m = (l+r)/2;
if(tr[idx*2] >= x && m >= ql) find(ql, x, idx*2, l, m);
if(pos==1e9) find(ql, x, idx*2+1, m+1, r);
}
signed main(){
fastio
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i++){
cin >> arr[i];
}
build(1, 0, n-1);
for(int i = 0;i < m;i++){
int op;
cin >> op;
if(op==1){
int i, v;
cin >> i >> v;
update(i, v, 1, 0, n-1);
}else{
int x, l;
cin >> x >> l;
pos = 1e9;
find(l, x, 1, 0, n-1);
cout << (pos == 1e9 ? -1 : pos) << "\n";
}
}
}int query(int ql, int qr, int idx, int l, int r){
if(ql <= l && r <= qr){
return tr[idx];
}
int m = (l+r)/2;
if(ql > m){
return query(ql, qr, idx*2+1, m+1, r);
}
if(qr <= m){
return query(ql, qr, idx*2, l, m);
}
//修改合併函數!
return combine(query(ql, qr, idx*2, l, m), query(ql, qr, idx*2+1, m+1, r));
}struct node{
ll ans, left, right, sum;
node(){}
node(ll a, ll b, ll c, ll d){
ans = a, left = b, right = c, sum = d;
}
};
node combine(node a, node b){
node c;
c.ans = max({a.ans, b.ans, a.right+b.left});
c.left = max(a.sum+b.left, a.left);
c.right = max(a.right+b.sum, b.right);
c.sum = a.sum + b.sum;
return c;
}#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
struct node{
ll ans, left, right, sum;
node(){}
node(ll a, ll b, ll c, ll d){
ans = a, left = b, right = c, sum = d;
}
};
const int MAXN = 1e5+5;
node tr[MAXN*4];
int arr[MAXN];
node combine(node a, node b){
node c;
c.ans = max({a.ans, b.ans, a.right+b.left});
c.left = max(a.sum+b.left, a.left);
c.right = max(a.right+b.sum, b.right);
c.sum = a.sum + b.sum;
return c;
}
void build(int idx, int l, int r){
if(l==r){
tr[idx] = node(arr[l],arr[l],arr[l],arr[l]);
}else{
int m = (l+r)/2;
build(idx*2,l,m);
build(idx*2+1,m+1,r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
}
void update(int pos, int val, int idx, int l, int r){
if(l==r){
tr[idx] = node(val,val,val,val);
return;
}
int m = (l+r)/2;
if(pos <= m) update(pos, val, idx*2, l, m);
else update(pos, val, idx*2+1, m+1, r);
tr[idx] = combine(tr[idx*2],tr[idx*2+1]);
}
node query(int ql, int qr, int idx, int l, int r){
if(ql <= l && r <= qr){
return tr[idx];
}
int m = (l+r)/2;
if(ql > m){
return query(ql, qr, idx*2+1, m+1, r);
}
if(qr <= m){
return query(ql, qr, idx*2, l, m);
}
return combine(query(ql, qr, idx*2, l, m), query(ql, qr, idx*2+1, m+1, r));
}
signed main(){
fastio
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i++){
cin >> arr[i];
}
build(1, 0, n-1);
cout << (tr[1].ans < 0 ? 0 : tr[1].ans) << "\n";
for(int i = 0;i < m;i++){
int p, v;
cin >> p >> v;
update(p, v, 1, 0, n-1);
cout << (tr[1].ans < 0 ? 0 : tr[1].ans) << "\n";
}
}