D题
二分轮次,每个小于x的人都要补充到x才能撑过x轮。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int n , a[maxn] ;
bool ok(ll x)
{
ll res = 0 ;
rep(i , 1 , n) if(a[i] < x) res += x - a[i] ;
return res <= x ;
}
int main()
{
ios ;
int T ;
int cas = 0 ;
cin >> T ;
while(T --)
{
cin >> n ;
rep(i , 1 , n) cin >> a[i] ;
ll l = 0 , r = 2e9 ;
ll ans = l ;
while(l <= r)
{
ll mid = (l + r) / 2 ;
if(ok(mid)) ans = mid , l = mid + 1 ;
else r = mid - 1 ;
}
cout << "Case #" << ++ cas << ": " << ans + 1 << '\n' ;
}
return 0 ;
}
J题
不好意思,我看到题就直接去魔改吉司机线段树了。区间取最大值,区间查询最大值。直接做就行了。
不过如果你对亮度排序后,直接区间覆盖就好了。。。裸的线段树就行了。
如果你像我一样只会莽的话会写的比较慢一些。区间覆盖就好写很多了。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 1e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int n , m , a[maxn] ;
struct jls_seg
{
int mn[maxn << 2] , se_mn[maxn << 2] ;
int mx[maxn << 2] ;
int ls(int x)
{
return x << 1 ;
}
int rs(int x)
{
return x << 1 | 1 ;
}
void push_up(int id)
{
mx[id] = max(mx[ls(id)] , mx[rs(id)]) ;
mn[id] = min(mn[ls(id)] , mn[rs(id)]) ;
se_mn[id] = min(se_mn[ls(id)] , se_mn[rs(id)]) ;
if(mn[ls(id)] != mn[rs(id)]) se_mn[id] = min(se_mn[id] , max(mn[ls(id)] , mn[rs(id)])) ;
}
void dec_tag(int id , int v)
{
if(v <= mn[id]) return ;
mn[id] = v ;
mx[id] = max(mx[id] , v) ;
}
void push_down(int id)
{
dec_tag(ls(id) , mn[id]) ;
dec_tag(rs(id) , mn[id]) ;
}
void init()
{
rep(i , 1 , m << 2) mx[i] = 0 , mn[i] = 0 , se_mn[i] = inf ;
}
void update(int id , int l , int r , int x , int y , int v)
{
//if(v <= mn[id]) return ;
if(r < l || y < x || v <= mn[id]) return ;
//ddebug(l , r) ;
if(l == x && r == y && v < se_mn[id])
{
//debug(222) ;
dec_tag(id , v) ;
return ;
}
push_down(id) ;
int mid = (l + r) / 2 ;
if(y <= mid) update(ls(id) , l , mid , x , y , v) ;
else if(x > mid) update(rs(id) , mid + 1 , r , x , y , v) ;
else update(ls(id) , l , mid , x , mid , v) , update(rs(id) , mid + 1 , r , mid + 1 , y , v) ;
push_up(id) ;
}
int query_max(int id , int l , int r , int x , int y)
{
// debug(mx[id]) ;
if(l == x && r == y) return mx[id] ;
push_down(id) ;
int mid = (l + r) / 2 ;
if(y <= mid) return query_max(ls(id) , l , mid , x , y) ;
else if(x > mid) return query_max(rs(id) , mid + 1 , r , x , y) ;
else return max(query_max(ls(id) , l , mid , x , mid) , query_max(rs(id) , mid + 1 , r , mid + 1 , y)) ;
}
} seg ;
void solve(int cas)
{
cin >> n >> m ;
rep(i , 1 , m) a[i] = 0 ;
rep(i , 1 , n)
{
int t , x ;
cin >> t >> x ;
int tmp = min(t , m) ;
a[tmp] = max(a[tmp] , x) ;
}
seg.init() ;
rep(t , 1 , m) for(int j = 1 ; j <= m ; j += 2 * t) seg.update(1 , 1 , m , j , j + t - 1 , a[t]) ;
cout << "Case #" << cas << ": " ;
rep(i , 1 , m) cout << seg.query_max(1 , 1 , m , i , i) << " \n"[i == m] ;
}
int main()
{
ios ;
int T ;
cin >> T ;
rep(i , 1 , T) solve(i) ;
return 0 ;
}
K题
奇数就拆成奇数和偶数,答案是1。
偶数凭借直感,要么分成2个数,要么分成3个数,打个表规律就全出来了,分成两个数周期是2,分成3个数周期是3,取个最小值就行了。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
int main()
{
ios ;
int T ;
cin >> T ;
rep(cas , 1 , T)
{
int x ;
cin >> x ;
if(x == 6) cout << "Case #" << cas << ": " << -1 << '\n' ;
else if(x % 2 == 1) cout << "Case #" << cas << ": " << 1 << '\n' ;
else
{
if(x % 6 == 0) cout << "Case #" << cas << ": " << 2 << '\n' ;
else if(x % 6 == 2)
{
int ans = 4 ;
if(abs(x - 14) % 18 != 0) ans = 3 ;
if(abs(x - 14) % 12 == 6) ans = 2 ;
cout << "Case #" << cas << ": " << ans << '\n' ;
}
else
{
int ans = 4 ;
if(abs(x - 22) % 18 != 0) ans = 3 ;
if(abs(x - 22) % 12 == 6) ans = 2 ;
cout << "Case #" << cas << ": " << ans << '\n' ;
}
}
}
return 0 ;
}
L题
跟这位哥学的。
#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cl(x) x.clear()
#define all(x) x.begin() , x.end()
#define rep(i , x , n) for(int i = x ; i <= n ; i ++)
#define per(i , n , x) for(int i = n ; i >= x ; i --)
#define mem0(x) memset(x , 0 , sizeof(x))
#define mem_1(x) memset(x , -1 , sizeof(x))
#define mem_inf(x) memset(x , 0x3f , sizeof(x))
#define debug(x) cerr << #x << " = " << x << '\n'
#define ddebug(x , y) cerr << #x << " = " << x << " " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 1e9 + 7 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
struct Easymath
{
ll qpow(ll a , ll b) //快速幂
{
if(b < 0) return 0 ;
ll ans = 1 ;
a %= mod ;
while(b)
{
if(b & 1) ans = (ans * a) % mod ;
b >>= 1 , a = (a * a) % mod ;
}
return ans % mod ;
}
ll ksc_log(ll x , ll y , ll mod) //快速乘
{
x %= mod , y %= mod ;
ll ans = 0;
while(y)
{
if(y & 1) ans = (ans + x) % mod ;
y >>= 1 ;
x = (x + x) % mod ;
}
return ans;
}
ll ksc_O1(ll x , ll y , ll mod) //快速乘
{
x %= mod , y %= mod ;
ll z = (ld)x * y / mod ;
ll ans = x * y - z * mod ;
if(ans < 0) ans += mod ;
else if(ans >= mod) ans -= mod ;
return ans ;
}
int cnt = 0 ;
bool vis[maxn] ;
int prime[maxn] ;
void get_prime(int up) //素数筛
{
memset(vis , 0 , sizeof(vis)) ;
vis[1] = 1 ;
for(int i = 2 ; i <= up ; i ++)
{
if(!vis[i])
prime[++ cnt] = i ;
for(int j = 1 ; j <= cnt && i * prime[j] <= up ; j ++)
{
vis[i * prime[j]] = 1 ;
if(i % prime[j] == 0) break ;
}
}
}
//begin 判定大素数
ll mul(ll a , ll b , ll mod)
{
ll ret = 0 ;
while(b)
{
if(b & 1) ret = (ret + a) % mod ;
a = (a + a) % mod ;
b >>= 1 ;
}
return ret ;
}
ll pow(ll a , ll b , ll mod)
{
ll ret = 1 ;
while(b)
{
if(b & 1) ret = mul(ret , a , mod) ;
a = mul(a , a , mod) ;
b >>= 1 ;
}
return ret ;
}
bool check(ll a , ll n)
{
ll x = n - 1 ;
int t = 0 ;
while((x & 1) == 0)
{
x >>= 1 ;
t ++ ;
}
x = pow(a , x , n) ;
ll y ;
rep(i , 1 , t)
{
y = mul(x , x , n) ;
if(y == 1 && x != 1 && x != n - 1) return 1 ;
x = y ;
}
if(y != 1) return 1 ;
return 0 ;
}
bool Miller_Rabin(ll n)
{
if(n == 2) return 1 ;
if(n == 1 || !(n & 1)) return 0 ;
const int arr[12] = {2,3,5,7,11,13,17,19,23,29,31,37} ;
rep(i , 0 , 11)
{
if(arr[i] >= n) break ;
if(check(arr[i] , n)) return 0 ;
}
return 1 ;
}
//end 判定大素数
ll get_inv(ll x) //逆元
{
return qpow(x , mod - 2) % mod ;
}
ll inv1[maxn] ; //乘法逆元
void init1(int up)
{
inv1[1] = 1 ;
for(int i = 2 ; i <= up ; i ++)
inv1[i] = (ll)(mod - mod / i) * inv1[int(mod % (ll)i)] % mod ;
}
ll fac[maxn] ;
ll inv[maxn] ; //阶乘逆元
void init(int up)
{
fac[0] = fac[1] = inv[0] = inv[1] = 1 ;
for(int i = 2 ; i <= up ; i ++)
{
fac[i] = fac[i - 1] * i % mod ;
inv[i] = -inv[mod % i] * (mod / i) % mod ;
while(inv[i] < 0) inv[i] += mod ;
}
for(int i = 2 ; i <= up ; i ++)
inv[i] = inv[i] * inv[i - 1] % mod ;
}
ll C(int n , int m)
{
return fac[n] * inv[m] % mod * inv[n - m] % mod ;
}
} em ;
int n ;
struct node
{
int a , x ;
bool operator < (const node &s) const
{
return a < s.a ;
}
} b[maxn] ;
bool can(int i , int j , ll &res)
{
int now = b[i].a ;
while(now < b[j].a && res >= 2) res /= 2 , now ++ ;
if(now == b[j].a)
{
res += b[j].x ;
return 1 ;
}
else return 0 ;
}
ll cal(int i , int j)
{
ll sum = 0 ;
per(k , j , i)
{
if(k == j) sum = sum * 2 % mod + b[k].x ;
else sum = sum * em.qpow(2 , b[k + 1].a - b[k].a) % mod + b[k].x ;
sum %= mod ;
}
sum = (sum + 1) % mod ;
return sum ;
}
int main()
{
ios ;
int T ;
cin >> T ;
rep(cas , 1 , T)
{
cin >> n ;
rep(i , 1 , n) cin >> b[i].a >> b[i].x ;
sort(b + 1 , b + n + 1) ;
ll ans = 1 ;
rep(i , 1 , n)
{
int j = i ;
ll res = b[i].x ;
while(j + 1 <= n && can(j , j + 1 , res)) j ++ ;
ans *= cal(i , j) ;
ans %= mod ;
i = j ;
}
cout << "Case #" << cas << ": " << ans << '\n' ;
}
return 0 ;
}