2023杭电多校04


题目来自: 2023“钉耙编程”中国大学生算法设计超级联赛(4)

Solved Rank A B C D E F G H I J K L
6 / 12 136 / 1200 - - O Ø - O O - - O O O
  • Ø 赛后通过
  • O 在比赛中通过
  • ! 尝试了但是失败了
  • - 没有尝试

C - Simple Set Problem

SOLUTION

排序后双指针

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int N = 1e6 + 10;
struct node{
int id,x;
bool operator<(const node &k) const{
return x<k.x;
}
}a[N];
int tot;
int vis[N];
void solve(){
int n,i,j,x,y,r,cnt,k,mx=2e9;
cin>>n;
tot=0;
for(i=1;i<=n;i++){
cin>>k;
for(j=1;j<=k;j++){
cin>>x;
a[++tot]={i,x};
}
}
sort(a+1,a+tot+1);
r=0;
cnt=0;
for(i=1;i<=tot;i++){
while(cnt<n&&r<tot){
r++;
if(vis[a[r].id]==0) cnt++;
vis[a[r].id]++;
}
if(cnt==n) mx=min(mx,a[r].x-a[i].x);
if(vis[a[i].id]==1) cnt--;
vis[a[i].id]--;
}
cout<<mx<<'\n';
}

int main(){
int T = 1;
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> T;
while(T--) solve();
return 0;
}

F - PSO

SOLUTION

签到题

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

void solve(){
int n,i,j;
long double l,r,cnt;
ll ans=0;
scanf("%d",&n);
if(n==2){
l=1;
r=1;
printf("%.9Lf %.9Lf\n",l,r);
return;
}
r=2;
l=2.*(n-1)/n;
printf("%.9Lf %.9Lf\n",l,r);
}

int main(){
int T = 1;
ios::sync_with_stdio(false);
cin >> T;
while(T--) solve();
return 0;
}

G - Guess

SOLUTION

推柿子+打表

柿子最后可以变成 $\prod \limits_{d|n} {(\frac{n}{d}) ^ {\mu(d)}}$ ,然后可以上大质数分解(Pollard Rho 算法),理论复杂度是 $O(n^{0.25})$,然后可以发现常数大的板子在hdoj根本过不去。

再继续打表可以发现,当 $n$ 可以写成 $p^k$ ( $p$ 是一个质数)时,答案是 $p$,否则答案是 $1$。那么可以枚举指数 $k$ 来做这个题( $k$ 的大小不会超过 $60$),时间复杂度 $O(60logn)$

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
#define gc()(is==it?it=(is=in)+fread(in,1,Q,stdin),(is==it?EOF:*is++):*is++)
const int Q = (1 << 24) + 1;
char in[Q], *is=in, *it=in, c;

void read(int &n){
for(n = 0; (c = gc()) < '0' || c > '9';);
for(; c <= '9' && c >= '0'; c = gc()) n = n * 10 + c - 48;
}

void read(ll &n){
for(n = 0; (c = gc()) < '0' || c > '9';);
for(; c <= '9' && c >= '0'; c = gc()) n = n * 10 + c - 48;
}

const int S = 8, modp = 998244353;

mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());

ll rng(ll l, ll r){
uniform_int_distribution<ll> uni(l, r);
return uni(mt);
}

ll mult_mod(ll a, ll b, ll c){
a %= c;
b %= c;
ll ret = 0;
ll tmp = a;
while(b){
if(b & 1){
ret += tmp;
if(ret > c) ret -= c;
}
tmp <<= 1;
if(tmp > c) tmp -= c;
b >>= 1;
}
return ret;
}

ll pow_mod(ll a, ll n, ll mod){
ll ret = 1;
ll temp = a % mod;
while(n){
if(n & 1) ret = mult_mod(ret, temp, mod);
temp = mult_mod(temp, temp, mod);
n >>= 1;
}
return ret;
}

bool check(ll a, ll n, ll x, ll t){
ll ret = pow_mod(a, x, n);
ll last = ret;
for(int i = 1; i <= t; i++){
ret = mult_mod(ret, ret, n);
if(ret == 1 && last != 1 && last != n - 1) return true;
last = ret;
}
if(ret != 1) return true;
return false;
}

bool Miller_Rabin(ll n){
if(n < 2) return false;
if(n == 2) return true;
if((n & 1) == 0) return false;
ll x = n - 1;
ll t = 0;
while((x & 1) == 0){
x >>= 1;
t++;
}

for(int i = 0; i < S; i++){
ll a = rng(1, n - 1);
if(check(a, n, x, t)) return false;
}
return true;
}

ll factor[105], fac[105];
int tol, tot;
ll gcd(ll a, ll b){
ll t;
while(b){
t = a;
a = b;
b = t % b;
}
if(a >= 0) return a;
return -a;
}

ll pollard_rho(ll x, ll c){
ll i = 1, k = 2;
ll x0 = rng(1, x - 1);
ll y = x0;
while(true){
i++;
x0 = (mult_mod(x0, x0, x) + c) % x;
ll d = gcd(y - x0, x);
if(d != 1 && d != x) return d;
if(y == x0) return x;
if(i == k){
y = x0;
k += k;
}
}
}

void findfac(ll n, int k){
if(n == 1) return;
if(tol >= 1) return;
if(Miller_Rabin(n)){
factor[tol++] = n;
return;
}
ll p = n;
int c = k;
while(p >= n) p = pollard_rho(p, c--);
findfac(p, k);
findfac(n / p, k);
}

ll n;

ll qpow(ll a, ll b){
ll res = 1;
while(b){
if(b & 1) res = res * a;
b >>= 1;
a = a * a;
}
return res;
}

void solve(){
cin >> n;
if(n == 1){
cout << "1\n";
return;
}
for(int i = 1; i <= 60; i++){
ll x = powl(n, 1. / i);
for(int j = -1; j <= 1; j++){
ll y = x + j;
if(y < 2) continue;
if(qpow(y, i) == n && Miller_Rabin(y)){
cout << y % modp << '\n';
return;
}
}
}
cout << "1\n";
}

int main(){
int T = 1;
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
// read(T);
cin >> T;
while(T--) solve();
return 0;
}

J - Kong Ming Qi

SOLUTION

雷伤杯秒了

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve(){
int n,i,j,x,y,r,cnt,k,m;
cin >> n >> m;
if (n>m) swap(n,m);
if (n==1) {
cout << (m+1)/2 << endl;
}else if (n==2) {
if (m%3==2) cout << 1 << endl;
else if (m%3==1) cout << 1 << endl;
else cout << 2 << endl;
}else {
if (n%3==0||m%3==0) {
cout << 2 <<endl;
}else {
cout << 1 << endl;
}
}
}

int main(){
int T = 1;
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
// read(T);
cin >> T;
while(T--) solve();
return 0;
}

K - Circuit

SOLUTION

枚举起点,用dij找最小环和方案数,然后把枚举过的点删掉防止算重。

时间复杂度 $O(nmlogn)$,貌似是数据弱的很。

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
const int N = 500 + 10, mod = 998244353, M = 500 * 500;
const ll inf = 1e18;

#define gc()(is==it?it=(is=in)+fread(in,1,Q,stdin),(is==it?EOF:*is++):*is++)
const int Q = (1 << 24) + 1;
char in[Q], *is=in, *it=in, c;

void read(int &n){
for(n = 0; (c = gc()) < '0' || c > '9';);
for(; c <= '9' && c >= '0'; c = gc()) n = n * 10 + c - 48;
}

void read(ll &n){
for(n = 0; (c = gc()) < '0' || c > '9';);
for(; c <= '9' && c >= '0'; c = gc()) n = n * 10 + c - 48;
}


struct Edge{
int v, id, w;
};

vector<Edge> e[N], g[N];
ll dis[N], dp[N];
int n, vise[M], vis[N];
ll ansd, ansp;

void gao(int x){
for(int i = 1; i <= n; i++){
dis[i] = inf;
dp[i] = vis[i] = 0;
}
dis[x] = 0;
dp[x] = 1;
ll tmpd = inf, tmpp = 0;
priority_queue<pll, vector<pll>, greater<pll>> q;
q.push({0, x});
while(!q.empty()){
int u = q.top().second;
ll dist = q.top().first;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(Edge eg : e[u]){
int v = eg.v, id = eg.id, w = eg.w;
if(vise[id]) continue;
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
dp[v] = dp[u];
q.push({dis[v], v});
}else if(dis[v] == dis[u] + w){
dp[v] += dp[u];
if(dp[v] >= mod) dp[v] -= mod;
}
}
}
for(Edge eg : g[x]){
int v = eg.v, id = eg.id, w = eg.w;
if(dis[v] + w < tmpd){
tmpd = dis[v] + w;
tmpp = dp[v];
}else if(dis[v] + w == tmpd){
tmpp += dp[v];
if(tmpp >= mod) tmpp -= mod;
}
vise[id] = 1;
}
for(Edge eg : e[x]){
int v = eg.v, id = eg.id, w = eg.w;
vise[id] = 1;
}
if(tmpd != inf){
if(ansd == -1 || tmpd < ansd){
ansd = tmpd;
ansp = tmpp;
}else if(ansd == tmpd){
ansp += tmpp;
if(ansp >= mod) ansp -= mod;
}
}
}

void solve(){
int m;
// cin >> n >> m;
read(n);read(m);
for(int i = 0, u, v, w; i < m; i++){
// cin >> u >> v >> w;
read(u);read(v);read(w);
e[u].push_back({v, i, w});
g[v].push_back({u, i, w});
vise[i] = 0;
}
ansd = ansp = -1;
for(int i = 1; i <= n; i++){
gao(i);
}
cout << ansd << ' ' << ansp << '\n';
for(int i = 1; i <= n; i++){
e[i].clear();
g[i].clear();
}
}

int main(){
int T = 1;
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
read(T);
// cin >> T;
while(T--) solve();
return 0;
}

L - a-b Problem

SOLUTION

签到题,按 $a+b$ 排序。

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define gc()(is==it?it=(is=in)+fread(in,1,Q,stdin),(is==it?EOF:*is++):*is++)
const int Q = (1 << 24) + 1;
char in[Q], *is=in, *it=in, c;

void read(int &n){
for(n = 0; (c = gc()) < '0' || c > '9';);
for(; c <= '9' && c >= '0'; c = gc()) n = n * 10 + c - 48;
}

void read(ll &n){
for(n = 0; (c = gc()) < '0' || c > '9';);
for(; c <= '9' && c >= '0'; c = gc()) n = n * 10 + c - 48;
}

const int N = 1e5 + 10;
struct node{
int x,y;
bool operator<(const node &k)const{
return x+y>k.x+k.y;
}
}a[N];
void solve(){
int n,i,j,x,y,l,r;
ll ans=0;
cin>>n;
for(i=1;i<=n;i++){
cin>>a[i].x>>a[i].y;
}
sort(a+1,a+n+1);
for(i=1;i<=n;i++){
if(i&1){
ans+=a[i].x;
}
else ans-=a[i].y;
}
cout<<ans<<'\n';
}

int main(){
int T = 1;
ios::sync_with_stdio(false);
// read(T);
cin >> T;
while(T--) solve();
return 0;
}

D - Data Generation

SOLUTION

打表找规律

最后答案是 $(n - 1) \times (1 - (\frac{n - 2}{n})^m)$

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int mod = 998244353;

ll qpow(ll a, ll b){
a %= mod;
ll res = 1;
while(b){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}

void solve() {
ll n, m;
cin >> n >> m;
ll fm = qpow(n, m);
ll ans = qpow((n - 2 + mod) % mod, m) * qpow(fm, mod - 2) % mod;
ans = 1 - ans;
if(ans < 0) ans += mod;
ans = ans * ((n - 1 + mod) % mod) % mod;
cout << ans << '\n';
}

int main() {
int T = 1;
ios::sync_with_stdio(false);
cin >> T;
while (T--) solve();
return 0;
}