The 2021 CCPC Guilin Onsite B题 A Plus B Problem (线段树)

传送门

代码

#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define LL long long
#define pr pair<int,int>
#define mk(a,b) make_pair(a,b)
#define endl '\n'
#define ls (node << 1)
#define rs (node << 1 | 1)
using namespace std;
const int maxx = 1e6 + 10, N = (1 << 30) - 1;
int n, q, a[2][maxx], c[maxx], tr[maxx << 2], lazy[maxx << 2];
char s[maxx], t[maxx];
void push_up(int node){ tr[node] = tr[ls] | tr[rs]; }
void push_down(int node){
	if(lazy[node] == -1) return;
	tr[ls] = lazy[ls] = tr[rs] = lazy[rs] = lazy[node];
	lazy[node] = -1;
}
void build(int node, int l, int r){
	lazy[node] = -1;
	if(l >= r){ tr[node] = (1 << c[l]); return; }
	int mid = (l + r) >> 1;
	build(ls, l, mid); build(rs, mid + 1, r);
	push_up(node);
}
int query(int node, int l, int r, int pos){
	if(l >= r) return __builtin_ctz(tr[node]);
	push_down(node);
	int mid = (l + r) >> 1;
	if(pos <= mid) return query(ls, l, mid, pos);
	else return query(rs, mid + 1, r, pos);
}
void update(int node, int l, int r, int ql, int qr, int val){
	if(l >= ql && r <= qr){
		tr[node] = lazy[node] = val;
		return;
	}
	push_down(node);
	int mid = (l + r) >> 1;
	if(qr <= mid) update(ls, l, mid, ql, qr, val);
	else if(ql > mid) update(rs, mid + 1, r, ql, qr, val);
	else update(ls, l, mid, ql, mid, val), update(rs, mid + 1, r, mid + 1, qr, val);
	push_up(node);
}
int Find(int node, int l, int r, int ql, int qr, int val){ 
	if(!(tr[node] & val)) return 0;
	if(l >= r) return l;
	push_down(node);
	int mid = (l + r) >> 1;
	if(l >= qr && r <= qr){
		if(tr[rs] & val) return Find(rs, mid + 1, r, ql, qr, val);
		else return Find(ls, l, mid, ql, qr, val);
	}
	else{
		if(qr <= mid) return Find(ls, l, mid, ql, qr, val);
		else if(ql > mid) return Find(rs, mid + 1, r, ql, qr, val);
		else{
			int tmp = Find(rs, mid + 1, r, mid + 1, qr, val); 
			if(tmp) return tmp;
			return Find(ls, l, mid, ql, mid, val);
		}
	}
}
int main(){
	ios::sync_with_stdio(false); cin.tie(0);
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
	freopen("output.out", "w", stdout);
#endif
	cin >> n >> q >> s + 1 >> t + 1;
	for(int i = n, add = 0; i >= 1; --i){
		a[0][i] = s[i] - '0', a[1][i] = t[i] - '0';
		c[i] = a[0][i] + a[1][i] + add;
		if(c[i] > 9){ c[i] -= 10; add = 1; }
		else add = 0;
	}
	build(1, 1, n);
	while(q--){
		int r, pos, val, delta;
		cin >> r >> pos >> val;
		delta = val - a[r - 1][pos];
		if(!delta){
			 cout << query(1, 1, n, pos) << " " << 0 << endl;
			 continue;
		}
		a[r - 1][pos] = val;
		int x = query(1, 1, n, pos) + delta, ans = 2;
		if(x < 0){
			x += 10;
			update(1, 1, n, pos, pos, 1 << x);
			int l = ((pos > 1) ? Find(1, 1, n, 1, pos - 1, N ^ 1) : 0);
			if(l + 1 <= pos - 1){ update(1, 1, n, l + 1, pos - 1, 1 << 9); ans += pos - 1 - l; }
			if(l){
				int y = query(1, 1, n, l) - 1;
				update(1, 1, n, l, l, 1 << y);
				++ans;
			}
		}
		else if(x > 9){
			x -= 10;
			update(1, 1, n, pos, pos, 1 << x);
			int l = ((pos > 1) ? Find(1, 1, n, 1, pos - 1, N ^ (1 << 9)) : 0);
			if(l + 1 <= pos - 1){ update(1, 1, n, l + 1, pos - 1, 1); ans += pos - 1 - l; }
			if(l){
				int y = query(1, 1, n, l) + 1;
				update(1, 1, n, l, l, 1 << y);
				++ans;
			}
		}
		else update(1, 1, n, pos, pos, 1 << x);
		cout << x << " " << ans << endl;
	}
	return 0;
}
posted @ 2021-11-16 10:38  Knowledge-Pig  阅读(69)  评论(0编辑  收藏  举报