下午周赛。
想抢T2首A结果虽然一眼秒了,但打慢了点,只拿到了second AC /kk。
然后先开了T3,开始不是很会,手玩了会样例,感觉是推式子,应该是推对了,但是写完挂成50分了,赛时没调出来。 赛后发现没考虑 26 ^ n % p 为 1 的情况,输麻了。
之后开了T1也是一眼瞄,只不过码的没T2快。
之后在后4题兜兜转转,能拿的分都尝试了一会,最终后四题只拿了30分,遗憾。
晚上订题。
T1, 将 a1 分解质因数,对于每个 gcd(a1, ai) 尝试除a1的每个质因数,找到能初的最小的质因数就好了,特判下 gcd 为 1 的情况。
code:
#include<bits/stdc++.h>
#define int long long
#define debug puts("原始人,启洞!");
using namespace std;
const int N = 1e5 + 10;
int a[N];
int pri[N], tot;
signed main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
int n;
scanf("%lld", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
int x = a[1];
for(int i = 2; i * i <= x; i++){
if(x % i == 0){
while(x % i == 0) x /= i;
pri[++tot] = i;
}
}
for(int i = 1; i <= n; i++){
int ans = __gcd(a[1], a[i]);
bool flag = 0;
for(int j = 1; j <= tot; j++)
if(ans % pri[j] == 0){
ans /= pri[j];
flag = 1;
// cout << ans;
break;
}
if(flag)
printf("%lld ", ans);
else{
if(ans != 1) printf("1 ");
else printf("-1 ");
}
}
return 0;
}//by hwl
T2,手玩后发现每个出现的关系都可以互相推出来,所以可以用并查集来维护下每个连通块,退后统计有多少连通块就好了。
code:
#include<bits/stdc++.h>
//#define int long long
#define debug puts("原始人,启洞!");
using namespace std;
const int N = 1e5 + 10;
int fa[N];
int find(int x){
if(x == fa[x]) return x;
else return fa[x] = find(fa[x]);
}
void merge(int x, int y){
x = find(x), y = find(y);
fa[x] = y;
return;
}
bool flag[N];
int main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++) fa[i] = i;
for(int _ = 1; _ <= m; _++){
int x, y, z;
cin >> x >> y >> z;
if(find(x) == find(y)) continue;
merge(x, y);
}
int ans = 0;
for(int i = 1; i <= n; i++){
int fa = find(i);
if(!flag[fa]){
flag[fa] = 1;
ans++;
}
}
cout << ans << endl;
return 0;
}//by hwl
T3,推式子,设长度为n,当前哈希值为x,下一个哈希值为y,要求的字符代表制为a,则具体式子就是解:
26 *(x - a * 26 ^ (n - 1))+ a = y
化简后就是:
a = (26 * x - y) / (26 ^ n - 1)
注意分母为零的情况。
code:
#include<bits/stdc++.h>
#define int long long
#define debug puts("原始人,启洞!");
using namespace std;
const int N = 1e5 + 10;
int a[N], v[N];
int qpow1(int a, int b, int mod){
int res = 1;
while(b){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int C_inv(int x, int mod){//快速幂——费马小定理求逆元
return qpow1(x, mod - 2, mod);
}
// vector<int> v;
signed main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
// int op = qpow(26, 5);
// int ans = (26 * 10 - (op - 1) * 18) % 31;
// cout << (ans + 31) % 31<< endl;
// ans *= C_inv(11881375, 31);
// ans = (op - 1) * 18 % 31;
// cout << ans << " " << (26 * 10 % 31 - 15 + 31) % 31 << endl;
// cout << ans / (op - 1) << endl;
// ans = (26 * 10 % 31 - 15 + 31) % 31 * C_inv(op - 1, 31);
// cout << (ans + 31) % 31<< endl;
int n, p, op;
cin >> n >> p;
op = qpow1(26, n, p);
if(op == 1){
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = n; i >= 1; i--){
v[i] = a[1] % 26;
a[1] /= 26;
}
for(int i = 1; i <= n; i++)
cout << char(v[i] + 'a');
cout << endl;
return 0;
}
// cout << op << endl;
int x, y, z;
cin >> x;
z = x;
for(int i = 1; i < n; i++){
cin >> y;
int ans = ((26 * x % p - y) % p + p) % p;
ans = (ans % p * (C_inv(op - 1, p) % p + p) % p) % p;
cout << char(ans + 'a');
x = y;
}
y = z;
int ans = ((26 * x % p - y) % p + p) % p;
ans = (ans % p * (C_inv(op - 1, p) % p + p) % p) % p;
cout << char(ans + 'a');
cout << endl;
return 0;
}//by hwl
T4,dp题(由于作者太懒了,打算鸽一会题解 (doge )
2024.3.15 补充:
因为操作方案相同我们构造出来的数列可能会不同。
于是我们想到一种方法。
枚举最开始哪一位的数。
然后dp。
但是这样会T。
那么我们的时间瓶颈在哪呢?
就是我们枚举最开始的那一位导致的。
那么我们可以强制规定末尾为零。
每次加a,减b,可以用差分的思想,将整个数列减去一个数,就保证了末尾为0啦。
code:
#include <bits/stdc++.h>
// #define int long long
using namespace std;
const int N = 1e3 + 10, mod = 100000007;
int f[N][N];
signed main(){
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int n, s, a, b;
cin >> n >> s >> a >> b;
f[0][0] = 1;
for(int i = 1; i < n; i++){
for(int j = 0; j < n; j++)
f[i][j] = (f[i - 1][((j - i * a) % n + n) % n] + f[i - 1][((j + i * b) % n + n) % n]) % mod;
}
cout << f[n - 1][(s % n + n) % n] % mod << endl;
return 0;
}//by hwl
T6:
模拟即可。(当然是假的)
分类讨论。
知道有红太狼的话,一次全部出掉肯定不劣。
所以显出红太狼。
然后知道有美羊羊的话,那么出了美羊羊就一定会有胜负。
所以必须自己能赢的时候才出美羊羊。
大致就是这样,具体可以理解代码。
code:
#include<bits/stdc++.h>
//#define int long long
#define debug puts("原始人,启洞!");
#define win1 puts("Meiyangyang");
#define win2 puts("Xiyangyang");
#define Draw puts("Draw");
using namespace std;
const int N = 10;
struct Hwl{
int hui, xi, hong, mei;
}a, b;
int main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
int T;
cin >> T;
while(T--){
cin >> a.hui >> a.xi >> a.hong >> a.mei;
cin >> b.hui >> b.xi >> b.hong >> b.mei;
if(a.hong != 0){
if(b.hui - a.hong < 0){
win1;
continue;
}else b.hui -= a.hong;
a.hong = 0;
}
if(a.mei != 0){
if(a.hui >= b.hui){
win1;
continue;
}
}
if(b.xi == 0 && a.hui != 0){
win1;
continue;
}
if(b.hong != 0){
if(a.hui - b.hong < 0){
win2;
continue;
}else a.hui -= b.hong;
b.hong = 0;
}
if(b.mei != 0){
if(b.hui >= a.hui){
win2;
continue;
}
}
if(a.xi == 0 && b.hui != 0){
win2;
continue;
}
// if(a.mei == 0 && b.mei == 0){ //b.mei == 0 a.mei == 0
// int x = 0x3f3f3f3f, y = 0x3f3f3f3f;
// if(a.hui > b.xi) x = b.xi + 1;
// if(b.hui > a.xi) y = a.xi + 1;
// if(x == 0x3f3f3f3f && y == 0x3f3f3f3f){
// Draw;
// continue;
// }
// if(x <= y){
// win1;
// continue;
// }else{
// win2;
// continue;
// }
// }
//
// if(a.mei == 0 && b.mei == 1){ //a.mei == 0 b.mei == 1
// int x = 0x3f3f3f3f, y = 0x3f3f3f3f;
// if(a.hui > b.xi) x = b.xi + 1;
// if(b.hui > a.xi) y = a.xi + 1;
// if(a.hui - b.hui + 1 >= b.xi) y = min(y, a.hui - b.hui + 1);
// if(x == 0x3f3f3f3f && y == 0x3f3f3f3f){
// Draw;
// continue;
// }
// if(x <= y){
// win1;
// continue;
// }else{
// win2;
// continue;
// }
// }
//
// if(a.mei == 1 && b.mei == 0){ //a.mei == 1 b.mei == 0
// int x = 0x3f3f3f3f, y = 0x3f3f3f3f;
// if(a.hui > b.xi) x = b.xi + 1;
// if(b.hui > a.xi) y = a.xi + 1;
// if(b.hui - a.hui + 1 >= a.xi) x = min(x, b.hui - a.hui + 1);
// if(x == 0x3f3f3f3f && y == 0x3f3f3f3f){
// Draw;
// continue;
// }
// if(x <= y){
// win1;
// continue;
// }else{
// win2;
// continue;
// }
// }
//
// if(a.mei == 1 && b.mei == 1){
// int x = 0x3f3f3f3f, y = 0x3f3f3f3f;
// if(a.hui > b.xi) x = b.xi + 1;
// if(b.hui > a.xi) y = a.xi + 1;
// if(a.hui - b.hui + 1 >= b.xi) y = min(y, a.hui - b.hui + 1);
// if(b.hui - a.hui + 1 >= a.xi) x = min(x, b.hui - a.hui + 1);
// if(x == 0x3f3f3f3f && y == 0x3f3f3f3f){
// Draw;
// continue;
// }
// if(x <= y){
// win1;
// continue;
// }else{
// win2;
// continue;
// }
// }
int x = 0x3f3f3f3f, y = 0x3f3f3f3f;
if(!b.mei && a.hui > b.xi) x = b.xi + 1;
else if(b.mei && a.hui - b.hui > b.xi) x = b.xi + 1;
if(!a.mei && b.hui > a.xi) y = a.xi + 1;
else if(a.mei && b.hui - a.hui > a.xi) y = a.xi + 1;
if(x == y && x == 0x3f3f3f3f){
Draw;
continue;
}
if(x <= y){
if (b.hui >= x - 1 && x - 1 > a.xi){
Draw;
continue;
}
win1;
continue;
}
else{
if(a.hui > b.hui + 1 && a.hui >= y && y > b.xi){
Draw;
continue;
}
if(a.hui <= b.hui + 1 && a.hui >= y - 1 && y - 1 > b.xi){
Draw;
continue;
}
win2;
continue;
}
}
return 0;
}//by hwl