ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【CF780G】Andryusha and Nervous Barriers 题解

2022-07-20 08:32:10  阅读:133  来源: 互联网

标签:pq res int 题解 mn mid Nervous Barriers 挡板


CF 传送门:CF780G Andryusha and Nervous Barriers

模拟 + 线段树套小根堆。

Solution

赛时读不懂题?想象力过于差劲。(审题错误

上来发现直接模拟:给每一列都开一个小根堆(优化),内部插入这一列上方某一高度(行)有几个球存在,即初始时每一列都插入 make_pair(h+1,1)。然后将挡板按高度从大到小排序(球肯定先到达高的挡板)。然后按序遍历所有挡板,对于一个挡板 \(i\) 的列区间范围 \([l_i,r_i]\) 内的每一列,都在其小根堆中查找有多少个球满足 \(h\leq s_i+u_i\),统计完所有列的、能掉出去的球的总数之后,再根据挡板位置把它们插入另外一列的小根堆并修改高度即可。

啊然后你就可以成功地 TLE 了。

要加上一个优化:若列区间 \([i,j]\) 中所有球的高度 的最小值大于 \(s_i+u_i\),那就不需要再去统计这个区间了。这个使用线段树维护即可。

啊然后你就可以成功卡过此题。所以说赛时多加加有的没的优化总是好的。

Code

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define rep(i, a, b) for(register int i = a; i <= b; ++i)
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
const int maxn = 1e5 + 5, mod = 1e9 + 7, inf = 0x3f3f3f3f;
int h, w, n;
struct bz{
	int u, l, r, s;
}b[maxn]; 
struct tree{
	int mn;
	priority_queue <pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pq;
}t[maxn << 2];
bool operator <(bz const &x, bz const &y){
	return x.u > y.u;
}

inline void up(int x){
	t[x].mn = min(t[ls(x)].mn, t[rs(x)].mn);
}

inline void build(int i, int l, int r){
	if(l == r){
		t[i].pq.push(make_pair(h + 1, 1));
		t[i].mn = h + 1; return;
	} int mid = l + r >> 1;
	build(ls(i), l, mid), build(rs(i), mid + 1, r), up(i);
}

inline int query(int i, int l, int r, int L, int R, int x){
	if(t[i].mn > x) return 0;
	if(l == r){
		int res = 0;
		while(t[i].pq.top().first <= x and t[i].pq.size()){
			res = (res + t[i].pq.top().second) % mod, t[i].pq.pop();
		}
		if(t[i].pq.size()) t[i].mn = t[i].pq.top().first;
		else t[i].mn = inf; return res;
	} int mid = l + r >> 1, res = 0;
	if(L <= mid) res = (res + query(ls(i), l, mid, L, R, x)) % mod;
	if(R > mid) res = (res + query(rs(i), mid + 1, r, L, R, x)) % mod;
	up(i); return res % mod;	
}

inline void updt(int i, int l, int r, int pos, int x, int num){
	if(l == r){
		t[i].pq.push(make_pair(x, num));
		t[i].mn = t[i].pq.top().first; return;
	} int mid = l + r >> 1;
	if(pos <= mid) updt(ls(i), l, mid, pos, x, num);
	else updt(rs(i), mid + 1, r, pos, x, num); up(i);
}	
	
signed main(){
	scanf("%lld%lld%lld", &h, &w, &n);
	rep(i, 1, n) scanf("%lld%lld%lld%lld", &b[i].u, &b[i].l, &b[i].r, &b[i].s);
	sort(b + 1, b + n + 1);
	build(1, 1, w);
	rep(i, 1, n){
		int cnt = query(1, 1, w, b[i].l, b[i].r, min(h + 1, b[i].s + b[i].u));
		if(b[i].l == 1 and b[i].r == w) continue;
		if(b[i].l == 1) updt(1, 1, w, b[i].r + 1, b[i].u, cnt * 2);
		else if(b[i].r == w) updt(1, 1, w, b[i].l - 1, b[i].u, cnt * 2);
		else updt(1, 1, w, b[i].r + 1, b[i].u, cnt), updt(1, 1, w, b[i].l - 1, b[i].u, cnt);
	} printf("%lld\n", query(1, 1, w, 1, w, inf));
	return 0;
}

标签:pq,res,int,题解,mn,mid,Nervous,Barriers,挡板
来源: https://www.cnblogs.com/gsn531/p/16496509.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有