贝壳找房户外拓展(中等) 扫描线

https://nanti.jisuanke.com/t/27118

在线段树上写了矩阵乘法,其实只是2*2的矩阵,手写转移似乎更好。

#include<bits/stdc++.h>
using namespace std;
const int mo = 323232323;
const int maxn = 1e5 + 100;
struct I_node{
	int p, q, x, y, flog, k;
	bool operator < (const I_node & u)const{
		if(x == u.x)
		return flog > u.flog;
		return x < u.x; 
	}
}I[maxn * 2];
struct node{
	long long a[2][2];
	node(long long x = 0){
		for(int i = 0; i < 2; i++){
			for(int j = 0; j < 2; j++){
				a[i][j] = x;
			}
		}
	}
	node operator * (node u)const{
		node c(0);
		for(int i = 0; i < 2; i++){
			for(int k = 0; k < 2; k++){
				if(a[i][k])
				for(int j = 0; j < 2; j++){
					c.a[i][j] = (c.a[i][j] + a[i][k] * u.a[k][j]) % mo;
				} 
			} 
		}
		return c;
	}
}one, change;
node seg[maxn << 2];
void pushup(int node){
	seg[node] = seg[node << 1] * seg[node << 1 | 1]; 
} 
void build(int l, int r, int node){
	if(l == r){
		seg[node] = one;
		return ;
	}
	int mid = (l + r) >> 1;
	build(l, mid, node << 1);
	build(mid + 1, r, node << 1 | 1);
	pushup(node);
	return ; 
}
void update(int ind, int l, int r, int node){
	if(l == r){
		seg[node] = change;
		return ;
	}
//	cout << l << " " << r << endl;
	int mid = (l + r) >> 1;
	if(ind <= mid){
		update(ind, l, mid, node << 1);
	}
	else{
		update(ind, mid + 1, r, node << 1 | 1); 
	}
	pushup(node);
	return ;
}
node query(int le, int ri, int l, int r, int node){
	if(l >= le && r <= ri){
		return seg[node];
	}
	int mid = (l + r) >> 1;
	if(le <= mid && ri > mid){
		return query(le, ri, l, mid, node << 1) * query(le, ri, mid + 1, r, node << 1 | 1); 
	}
	else if(le <= mid){
		return query(le, ri, l, mid, node << 1);
	}
	else if(ri > mid){
		return query(le, ri, mid + 1, r, node << 1 | 1);
	}
}

void pri(node u){
	for(int i = 0; i < 2; i++){
		for(int j = 0; j < 2; j++){
			cout << u.a[i][j] << " ";
		}
		cout << endl;
	}
}
int book[maxn];
long long ans[maxn];
int main(){
	one.a[0][1] = one.a[1][0] = 0;
	for(int i = 0; i < 2; i++){
		one.a[i][i] = 1;
	}
	int n, m, Q, l, r, y, tp, tq, x;
	cin >> n >> m >> Q;
	char type[2];
	int k = 0;
	int In = 0, Qn = 0;
	while(Q--){
		scanf("%s", type);
		if(type[0] == 'I'){
			k++;
			scanf("%d %d %d %d %d", &l, &r, &y, &tp, &tq);
			I[In].p = tp, I[In].q = tq, I[In].k = k, I[In].flog = 1, I[In].x = l, I[In].y = y;
			In++;
			I[In].p = tp, I[In].q = tq, I[In].k = k, I[In].flog = -1, I[In].x = r, I[In].y = y;
			In++;
			book[k] = 1;
		}
		else if(type[0] == 'Q'){
			scanf("%d %d %d", &x, &l, &r);
			I[In].p = l, I[In].q = r, I[In].x = x;
			I[In].k = Qn++;
			I[In].flog = 0;
			In++;
		}
		else{
			scanf("%d", &l);
			book[l] = 0;
		}
	}
	build(1, m, 1);
	sort(I, I + In);
	for(int i = 0; i < In; i++){
		if(I[i].flog == 0){
	//	cout << I[i].flog << " " << I[i].x << " " << I[i].y << endl;
			node be(0);
			be.a[0][1] = 1;
			be = be * query(I[i].p, I[i].q, 1, m, 1);
			ans[I[i].k] = be.a[0][0];
		}
		else if(I[i].flog == 1){
			if(!book[I[i].k])
			continue;
	//	cout << I[i].flog << " " << I[i].x << " " << I[i].y << endl;
			change.a[0][0] = I[i].p;
			change.a[0][1] = 0;
			change.a[1][0] = I[i].q;
			change.a[1][1] = 1;
			update(I[i].y, 1, m, 1);
		}
		else{
			if(!book[I[i].k])
			continue;
	//	cout << I[i].flog << " " << I[i].x << " " << I[i].y << endl;
			change = one;
			update(I[i].y, 1, m, 1);
		}
	}
	for(int i = 0; i < Qn; i++){
		printf("%lld\n", ans[i]);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值