Hello 2023

1|0A. Hall of Fame


统计一下向左照的最靠右和向右照的最靠左的看是否可以把所有的位置都覆盖

#include <bits/stdc++.h> using namespace std; int read(){ int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1)+ch-'0' , ch = getchar(); return x; } void solve(){ int n = read(); string s; cin >> s; int l = 0 , r = n+1; for( int i = 1 ; i <= n ; i ++ ){ if( s[i-1] == 'L' ) l = i; else if( r == n+1 ) r = i; } // cout << l << " " << r << "\n"; if( r < l ) cout << "0\n"; else if( l+1 == r && r != n+1 && l != 0) cout << l << "\n"; else cout << "-1\n"; return; } int32_t main(){ for( int t = read() ; t ; t -- ) solve(); return 0; }

2|0B. MKnez's ConstructiveForces Task


首先应该很容易就能发现如果n是偶数的情况1,1,1,1就行了吧。

那么就是来求一下n为奇数的情况了。首先n=2k+1,然后根据题目得到

s1+s2+s3+=s1+s2=s2+s3=s3+s4

然后根据s1+s2=s2+s3可以推出s1=s3,继续推导可以得到s1=s3==s2k+1

同理可以推出s2=s4==s2k

x=s1=s3==s2k+1,y=s2=s4==s2k

s1+s2+s3+=s1+s2可以推出s3+s4++sn=0,代入上式可得

kx=(k1)yx=(k1),y=k即可

注意当n=3时可以解出x=0,但题目要求不等于零,所以此时无解

#include <bits/stdc++.h> using namespace std; int read(){ int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1)+ch-'0' , ch = getchar(); return x; } void solve(){ int n; cin >> n; if( n % 2 == 0 ) { cout << "YES\n"; for( int i = 1 ; i <= n ; i ++ ) cout << ( i & 1 ? 1 : -1 ) << " \n"[i==n]; } else if( n == 3 ) { cout << "NO\n"; } else{ cout << "YES\n"; int x = 1 - ( n + 1 ) / 2 , y = n / 2 - 1; for( int i = 1 ; i <= n ; i ++ ) cout << ( i & 1 ? y : x ) << " \n"[i==n]; } return; } int32_t main(){ ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr); int t; cin >> t; for( ; t ; t -- ) solve(); return 0; }

3|0C. Least Prefix Sum


题目的条件可以转换为,从m+1开始的前缀和大于0,从m1开始的后缀和小于 0

然后再求的过程中用优先队列维护前缀后缀中的数字。

#include <bits/stdc++.h> using namespace std; #define int long long int read(){ int x = 0 , f = 1 , ch = getchar(); while( ch != '-' && (ch < '0' || ch > '9') ) ch = getchar(); if( ch == '-' ) f = -1 , ch = getchar(); while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1)+ch-'0' , ch = getchar(); return x*f; } void solve(){ int n = read(), m = read(), res = 0; vector<int> a(n+1); for( int i = 1 ; i <= n ; i ++ ) a[i] = read(); priority_queue<int> q; for( int i = m , sum = 0 , u ; i > 1 ; i -- ){ sum += a[i] , q.push(a[i]); while( sum > 0 ) u = q.top(), q.pop() , sum -= u * 2 , q.push(-u), res ++; } priority_queue<int,vector<int>,greater<int>> p; for( int i = m+1 , sum = 0 , u ; i <= n ; i ++ ){ sum += a[i] , p.push(a[i]); while( sum < 0 ) u = p.top(), p.pop() , sum -= u * 2 , p.push(-u) , res ++; } printf("%lld\n" , res); return; } int32_t main(){ for( int t = read() ; t ; t -- ) solve(); return 0; }

4|0D. Boris and His Amazing Haircut


如果ai<bi则一定不可以。反之ai>=bi可以进行若干次操作。但要保证ai=bi或至少有一次操作x=bi

我们把x=bi称为关键操作,然后关键操作是可以合并的,我们要尽可能的合并关键操作,而合并关键操作的条件是xi=xj,且max(xi+1xj1)>=xi,所以我们要解决的问题就是区间查询最值,我选择使用 ST表解决

#include <bits/stdc++.h> using namespace std; int read(){ int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1)+ch-'0' , ch = getchar(); return x; } const int N = 2e5+5; int f[N][20] , log_2[N] , a[N] , b[N]; void solve(){ int n = read(); for( int i = 1 ; i <= n ; i ++ ) a[i] = read(); for( int i = 1 ; i <= n ; i ++ ) b[i] = read(); map<int,int> c; for( int m = read() , x ; m ; m -- ) x = read() , c[x] ++; map<int,vector<int>> cnt; for( int i = 1 ; i <= n ; i ++ ){ if( a[i] < b[i] ) return printf("NO\n") , void(); else if( a[i] == b[i] ) continue; cnt[ b[i] ].push_back(i); } for( int i = 1 ; i <= n ; i ++ ) f[i][0] = b[i]; for( int j = 1 ; j <= log_2[n] ; j ++ ) for( int i = 1; i + ( 1<<j) - 1 <= n ; i ++ ) f[i][j] = max( f[i][j-1] , f[i+(1<<j-1)][j-1] ); for( const auto &[k , v] : cnt ){ for( int i = 1 , l , r , s , t; i < v.size() ; i ++ ){ l = v[i-1] , r = v[i] , s = log_2[r - l + 1] , t = max( f[l][s] , f[r-(1<<s)+1][s] ); if( t <= k ) c[k] ++; } if( v.size() <= c[k] ) continue; printf("NO\n"); return; } printf("YES\n"); return; } int32_t main(){ log_2[0] = -1; for( int i = 1 ; i < N ; i ++ ) log_2[i] = log_2[i>>1] + 1; for( int t = read() ; t ; t -- ) solve(); return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17220292.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
历史上的今天:
2022-03-15 SMU ACM 2021划水赛
点击右上角即可分享
微信分享提示