2023 (ICPC) Jiangxi Provincial Contest -- Official Contest
A. Drill Wood to Make Fire
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int n , s , v;
cin >> n >> s >> v;
cout << (s * v >= n) << "\n";
}
int32_t main(){
int t;
cin >> t;
while( t -- )
solve();
return 0;
}
B. Wonderful Array
当对\(a[i]\)取模后,想满足后面的数比前面的数字小,实际上就是在累加的过程中跨过了\(m\),这样的话,可以先计算在不考虑\(x\)的情况下跨过了多少次\(m\),然后计算加上\(x\)后又会跨过多少次。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int k;
cin >> k;
vector<int> a(k);
for (auto &i: a) cin >> i;
int n, m, x;
cin >> n >> m >> x;
for (auto &i: a) i %= m;
vector<int> sum(k), cnt(k);
sum[0] = a[0];
for (int i = 1; i < k; i++) {
sum[i] = sum[i - 1] + a[i], cnt[i] = cnt[i - 1];
if (sum[i] >= m) sum[i] -= m, cnt[i]++;
}
int bn = 0, bcnt = 0;
x %= m;
sum[0] = 0;
cnt[0] = 0;
bn = x + (n / k) * sum[k - 1] + sum[n % k] - sum[0];
bcnt = (n / k) * cnt[k - 1] + cnt[n % k] - cnt[0] + bn / m;
cout << n - bcnt;
return 0;
}
I. Tree
对于路径上的边来说每个边都异或了一次,但是对于路径上的点来说,除了端点外的点都被异或了两次。所以异或操作可以理解为只对端点进行操作。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main(){
ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);
int n , q;
cin >> n >> q;
vector<int> g(n+1);
for( int x , y , z , i = 1 ; i < n ; i ++ ){
cin >> x >> y >> z;
g[x] ^= z , g[y] ^= z;
}
for( int op , x , y , z ; q ; q -- ){
cin >> op;
if( op == 1 ){
cin >> x >> y >> z;
g[x] ^= z , g[y] ^= z;
}else{
cin >> x;
cout << g[x] << "\n";
}
}
return 0;
}
J. Function
这题因为\(1\le a,b\le n\),所以始终都只有\(n\)个式子。首先我们知道对于询问\(a\),至少有一个解是\(b_a\)。然后我们先左右暴力的移动,最多移动\(\sqrt{b_a}\)次就一定会比最开始的解差。所以我们得到了一个复杂度\(O(n\log n)\)的做法
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main(){
ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);
int n;
cin >> n;
vector<int> b(n+1);
for( int i = 1 ; i <= n ; i ++ )
cin >> b[i];
int m;
cin >> m;
for( int op , x , y ; m ; m -- ){
cin >> op;
if( op == 0 ){
cin >> x >> y;
b[x] = min( b[x] , y );
}else{
cin >> x;
int res = b[x];
for( int i = x + 1 , j = 1 ; i <= n && j*j <= res ; i ++ , j ++ )
res = min( res , j*j + b[i] );
for( int i = x - 1 , j = 1 ; i >= 1 && j*j <= res ; i -- , j ++ )
res = min( res , j*j + b[i] );
cout << res << "\n";
}
}
return 0;
}
K. Split
一开始的时候序列a
保证了递减,并且操作实际上并不会改变递减的性质,甚至也不会改变差值。所以显然可以预处理除差分的序列。对于询问操作,实际上就是选择差分值最大的几个地方断开,这样可以回避掉差分值。
这样的话,就可以把差分值排序,然后求前缀和这样就可以每次\(O(1)\)的回答了。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
int32_t main(){
ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
for( int i = 0; i < n ; i ++ ) cin >> a[i];
vector<int> b;
b.push_back(0);
for( int i = 1 ; i < n ; i ++ ) b.push_back( a[i-1] - a[i]);
sort( b.begin() , b.end() );
for( int i = 1 ; i < b.size() ; i ++ )
b[i] += b[i-1];
int m;
cin >> m;
for( int op , x ; m ; m -- ){
cin >> op >> x;
if( op == 0 ) continue;
cout << b[ b.size() - x] << "\n";
}
return 0;
}
L. Zhang Fei Threading Needles - Thick with Fine
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main(){
int a;
cin >> a;
cout << a - 1 << "\n";
return 0;
}