专栏文章

8.9考试总结

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miof7a25
此快照首次捕获于
2025/12/02 18:13
3 个月前
此快照最后确认于
2025/12/02 18:13
3 个月前
查看原文

T1

发现答案要求的是 mm 之前有多少个,所以考虑到树状数组。
发现是单点修改,区间查询的模版。

T2

用线段树维护乘积。
把乘的节点变为 mm,除就改为 11

T3

发现这道题把 xx 排序后,就是求 yy 的最大上升子序列和。
用树状数组维护区间最值即可。
CPP
//Code by hhy
#include<bits/stdc++.h>
//#define int long long
#define ull unsigned long long
#define ll long long
using namespace std ;
const int kMaxN = 1e5 + 5 , MOD = 998244353 , INF = 1e18 ;
struct Edgepr
{
	int u , w ;
};
struct Edgeve
{
	int v , w ;
};
struct node
{
  int x , y , w ;
}a[kMaxN] ;
int n , m , k , len ;
int b[kMaxN] , dp[kMaxN] , c[kMaxN] ;
inline ll ksm(ll a , ll b)
{
	ll mul = 1 ;
	while(b)
	{
		if(b & 1) mul *= a , mul %= MOD ;
		a *= a ;
		a %= MOD ;
		b >>= 1 ;
	}
	return mul ;
}
int lowbit(int x)
{
	return (x & (-x)) ;
}
void update(int x , int k)
{
	while(x <= kMaxN - 1)
	{
		c[x] = max(c[x] , k) ;
		x += lowbit(x) ;
	}
}
int query(int x)
{
	int ans = 0 ;
	while(x)
	{
		ans = max(ans , c[x]) ;
		x -= lowbit(x) ;
	}
	return ans ;
}
bool cmp(node x , node y)
{
	if(x.x != y.x) return x.x < y.x ;
	return x.y < y.y ;
}
void work()
{
	cin >> n >> m >> k ;
	for( int i = 1 ; i <= k ; i++ )
	{
		cin >> a[i].x >> a[i].y >> a[i].w ;
		b[i] = a[i].y ;
	}
	sort(a + 1 , a + k + 1 , cmp) ;
	sort(b + 1 , b + k + 1) ;
	len = unique(b + 1 , b + k + 1) - (b + 1) ;
	for( int i = 1 ; i <= k ; i++ )
	{
		a[i].y = lower_bound(b + 1 , b + len + 1 , a[i].y) - b ;
	}
	int maxn = 0 ;
	for( int i = 1 ; i <= k ; i++ )
	{
		dp[i] = query(a[i].y) + a[i].w ;
		update(a[i].y , dp[i]) ;
		maxn = max(maxn , dp[i]) ;
	}
	cout << maxn ; 
}
signed main()
{
//	freopen(".in" , "r" , stdin) ;
//	freopen(".out" , "w" , stdout) ;
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0) ;
  int t = 1 ;
  // cin >> t ;
  while(t--) work() ;
  return 0 ;
}



T4

发现第一个提问就是 lazylazy 求最大值。
对于第二个提问,用线段树维护区间最小值,对于其他的,用分治的思想,从最小点两边开始找次小值,用优先队列维护即可。
CPP
//Code by hhy
#include<bits/stdc++.h>
//#define int long long
#define ull unsigned long long
#define ll long long
using namespace std ;
const int kMaxN = 5e5 + 5 , MOD = 998244353 , INF = 1e9 ;
struct Edgepr
{
	int u , w ;
};
struct Edgeve
{
	int v , w ;
};
struct node
{
  int l , r , w , p ;
  bool operator < (const node &a) const
  {
  	return w > a.w ;
	}
};
int n , m ; 
ll minn[kMaxN << 2] , pos[kMaxN << 2] , lazy[kMaxN << 2] , w[kMaxN] ;
vector<int> vec ;
priority_queue<node> q ;
#define lson(x) x << 1 
#define rson(x) (x << 1) | 1 
void push_up(int k)
{
	minn[k] = INF ;
	if(minn[lson(k)] < minn[k])
	{
		minn[k] = minn[lson(k)] ;
		pos[k] = pos[lson(k)] ;
	}
	if(minn[rson(k)] < minn[k])
	{
		minn[k] = minn[rson(k)] ;
		pos[k] = pos[rson(k)] ;
	}
}
void build(int k , int l , int r)
{
	if(l == r)
	{
		minn[k] = w[l] ;
		pos[k] = l ;
		return ;
	}
	int mid = (l + r) >> 1 ;
	build(lson(k) , l , mid) ;
	build(rson(k) , mid + 1 , r) ;
	push_up(k) ;
}
void push_down(int k)
{
	if(lazy[k] == 0) return ;
	lazy[lson(k)] = max(lazy[lson(k)] , lazy[k]) ;
	lazy[rson(k)] = max(lazy[rson(k)] , lazy[k]) ;
	minn[lson(k)] = max(minn[lson(k)] , lazy[k]) ;
	minn[rson(k)] = max(minn[rson(k)] , lazy[k]) ;
	lazy[k] = 0 ;
}
void update(int L , int R , ll v , int k , int l , int r)
{
	if(l >= L && r <= R)
	{
		minn[k] = max(v , minn[k]) ;
		lazy[k] = max(v , lazy[k]) ;
		return ;
	}
	push_down(k) ;
	int mid = (l + r) >> 1 ;
	if(L <= mid)
	{
		update(L , R , v , lson(k) , l , mid) ;
	}
	if(R > mid)
	{
		update(L , R , v , rson(k) , mid + 1 , r) ;
	}
	push_up(k) ;
}
pair<int , int> query(int L , int R , int k , int l , int r)
{
	if(L <= l && r <= R)
	{
		return {minn[k] , pos[k]} ;
	}
	if(L > R)
	{
		return {INF , 0} ;
	}
	push_down(k) ;
	pair<int , int> res = {INF , 0} ;
	int mid = (l + r) >> 1 ;
	if(L <= mid)
	{
		pair<int , int> p = query(L , R , lson(k) , l , mid) ;
		if(p.first < res.first)
		{
			res = p ;
		}
	}
	if(R > mid)
	{
		pair<int , int> p = query(L , R , rson(k) , mid + 1 , r) ;
		if(p.first < res.first)
		{
			res = p ;
		}
	}
	return res ;
}
void work()
{
	cin >> n ;
	for( int i = 1 ; i <= n ; i++ ) cin >> w[i] ;
	build(1 , 1 , n) ;
	cin >> m ;
	for( int i = 1 ; i <= m ; i++ )
	{
		int op ;
		cin >> op ;
		if(op == 1)
		{
			int l , r , k ;
			cin >> l >> r >> k ;
			update(l , r , k , 1 , 1 , n) ;
		}
		else
		{
			int l , r , k , x ;
			cin >> l >> r >> k >> x ;
			vec.clear() ;
			while(!q.empty()) q.pop() ;
			pair<int , int> p = query(l , r , 1 , 1 , n) ;
			q.push({l , r , p.first , p.second}) ;
			while(!q.empty())
			{
				node u = q.top() ;
				q.pop() ;
				if(u.w >= k) continue ;
				vec.push_back(u.w) ;
				pair<int , int> p1 = query(u.l , u.p - 1 , 1 , 1 , n) ;
				pair<int , int> p2 = query(u.p + 1 , u.r , 1 , 1 , n) ;
				q.push({u.l , u.p - 1 , p1.first , p1.second}) ;
				q.push({u.p + 1 , u.r , p2.first , p2.second}) ;
				if(vec.size() == x) break ;
			}
			if(vec.size() != x) cout << "-1\n" ;
			else
			{
				sort(vec.begin() , vec.end()) ;
				for( int i = 0 ; i < x ; i++ ) cout << vec[i] << " " ;
				cout << "\n" ;
			}
		}
	}
}
signed main()
{
//	freopen(".in" , "r" , stdin) ;
//	freopen(".out" , "w" , stdout) ;
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0) ;
  int t = 1 ;
//  cin >> t ;
  while(t--) work() ;
  return 0 ;
}


评论

0 条评论,欢迎与作者交流。

正在加载评论...