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;
}
posted @ 2023-05-25 21:27  PHarr  阅读(404)  评论(0编辑  收藏  举报