文章目录
前言
\quad 激动人心的新生月赛终于来了!经过一个多星期的比赛准备,这套题目呈现在大家面前。
\quad 为了尽量避免锅的出现,这次集结了 17,18,19 全部队员参与命题与验题工作,简直是 SDNU-ACM 有史以来最为浩大的工程(要是今天现场出锅就刺激了)。
\quad UPD:MD,今天还是出锅了。
说明
\quad 以下内容为现场赛时写的,一边看榜,一边写,所以是按照每道题被拿走FB的顺序写的。
题解
1616.Arithmetic Sequence[签到]
出题人:ymf \quad 验题人:lhr、wx、lzw
\quad 全场最简单的题目,于 00:02:57 被 2020Wangweiyi 拿走全场 First Blood!
题目大意
\quad 给出一个整数 S S S,要求你构造一个长度最短的等差数列,使其和为 S S S.
分析
\quad 直接输出 S S S 不就好啦.
\quad 小坑点: m a x ( S ) = I N T _ M A X + 1 max(S) = INT\_MAX + 1 max(S)=INT_MAX+1,需要使用 l o n g l o n g long\; long longlong 读入.
\quad 时间复杂度: O ( 1 ) O(1) O(1).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e5;
const int N = (int)1e5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)998244353;
void work()
{
ll s; scanf("%lld", &s);
printf("%lld\n", s);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1625.星球大战1[思维 + 枚举]
出题人:lra \quad 验题人:lhr、lzw
\quad 00:52:10 FB 诞生,By:ronargo
题目大意
\quad
如上图所示,在一个平面直角坐标系的以
(
0
,
0
)
(0,0)
(0,0) 为左下角、
(
N
,
N
)
(N,N)
(N,N) 为右上角的矩形中,求在原点向周围看去,能看到多少个点。
分析
\quad 不难(用)证明,一个点 ( x , y ) (x,y) (x,y) 能被看到当且仅当 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1.
\quad 由于 n n n 最大只有 2000 2000 2000,因此我们可以暴力枚举 x x x 和 y y y,时间复杂度为 O ( n 2 l o g ( n ) ) O(n^2log(n)) O(n2log(n)).
\quad 小坑点:特判 n = 1 n=1 n=1 的情形.
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e6;
const int N = (int)5e3;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 7;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
void work()
{
int n; scanf("%d", &n);
if(n == 1)
{
printf("0\n");
return;
}
int ans = 3;
for(int i = 1; i <= n - 1; ++i) for(int j = 1; j <= n - 1; ++j) ans += (gcd(i, j) == 1);
printf("%d\n", ans - 1);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1622.蓝精精的浏览器[栈模拟]
出题人:qp \quad 验题人:lhr
\quad 00:57:30 FB 诞生,By:20luwei
题目大意
\quad 题面简单易懂(没看懂的去骂 qp 吧)
分析
\quad 之前 lzw 讲过括号匹配,跟这道题很是相似,直接看代码吧.
\quad 时间复杂度: O ( 能 过 ) O(能过) O(能过).
代码实现
\quad 20luwei 小伙汁代码写得不错,就把你的放出来吧!
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cmath>
#include <stack>
using namespace std;
stack<string> a;
stack<string> b;
string t;
string s;
int forward = 0, back = 0;
int main()
{
a.push("http://www.acm.org/");
while(cin >> t)
{
if(t == "VISIT")
{
while(!b.empty()) b.pop();
cin >> s;
a.push(s);
cout << a.top() << '\n';
}
else if(t == "BACK")
{
if(a.size() != 1)
{
b.push(a.top());
a.pop();
cout << a.top() << '\n';
}
else
{
cout << "Ignored" << '\n';
}
}
else if(t == "FORWARD")
{
if(!b.empty())
{
a.push(b.top());
b.pop();
cout << a.top() << '\n';
}
else cout << "Ignored" << '\n';
}
else if(t == "QUIT") break;
}
return 0;
}
1623.闷声发大财[小思维]
出题人:sly \quad 验题人:lhr、lzw
\quad 01:56:22 FB 诞生,By:2020Wangweiyi 。
\quad
两个一血了啊,不愧是你!
题目大意
\quad 中文题
分析
\quad 代码里写了注释,自己模拟一下就懂了.
\quad 时间复杂度: O ( m ) O(m) O(m).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e5;
const int N = (int)5e3;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 7;
int n, m;
bool r[M + 5];
bool c[M + 5];
int rcnt, ccnt;
void work()
{
scanf("%d %d", &n, &m);
rcnt = n, ccnt = n;
for(int i = 1, x, y; i <= m; ++i)
{
scanf("%d %d", &x, &y);
if(!r[x]) r[x] = 1, --rcnt;
if(!c[y]) c[y] = 1, --ccnt;
printf("%lld%c", 1ll * rcnt * ccnt, i == m ? '\n' : ' ');
}
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1626.星球大战2[欧拉函数前缀和]
出题人:lra \quad 验题人:lhr、zlk、xwj、lzw、xsh
\quad 再次被 2020Wangweiyi 于03:11:30拿走 First Blood 。
题目大意
\quad 同 1625.星球大战1
分析
\quad 接 1625.星球大战1 的分析
\quad 用力推一下式子,发现答案就是 3 + 2 ∑ i = 1 n − 1 φ ( i ) 3 + 2\sum_{i=1}^{n-1}{\varphi(i)} 3+2∑i=1n−1φ(i),套上线性筛直接搞就行.
\quad 时间复杂度: O ( n ) O(n) O(n).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)4e4;
const int N = (int)1e5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 7;
bool is_prime[M + 5];
int prime[M + 5], cnt;
int phi[M + 5];//欧拉函数
void init()
{
memset(is_prime, 1, sizeof(is_prime));
is_prime[0] = is_prime[1] = 0;
phi[1] = 1;
for(int i = 2; i <= M; ++i)
{
if(is_prime[i])
{
prime[++cnt] = i;
phi[i] = i - 1;
}
for(int j = 1; j <= cnt && i * prime[j] <= M; ++j)
{
is_prime[i * prime[j]] = 0;
if(i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
void work()
{
int n; scanf("%d", &n);
if(n == 1)
{
printf("0\n");
return;
}
ll ans = 3;
for(int i = 2; i <= n - 1; ++i) ans += 2 * phi[i];
printf("%lld\n", ans);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
init();
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1627.最短的题[枚举]
出题人:xwj \quad 验题人:lhr、lra,lzw
\quad 02:15:08 又又又又 被 2020wangweiyi 拿走 FB 。
题目大意
\quad 从 n 个数中选 n - 1 个数使得它们或和(或运算的和)最大,输出这个最大值.
分析
\quad 枚举哪一个数不选,暴力更新答案即可.
\quad 时间复杂度: O ( n ) O(n) O(n).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)4e4;
const int N = (int)1e5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 7;
int n;
ll a[M + 5];
int c[64];
void work()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%lld", &a[i]);
for(int j = 62; j >= 0; --j) c[j] += (a[i]>>j&1);
}
ll mx = 0;
for(int i = 1; i <= n; ++i)
{
for(int j = 62; j >= 0; --j) c[j] -= (a[i]>>j&1);
ll tmp = 0; for(int j = 62; j >= 0; --j) if(c[j]) tmp |= (1ll<<j);
mx = max(mx, tmp);
for(int j = 62; j >= 0; --j) c[j] += (a[i]>>j&1);
}
printf("%lld\n", mx);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
出题人更优秀的做法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-11;
const ll N = 1e5 + 10;
ll a[N], pre[N], las[N];
int main() {
ll n;
scanf("%lld", &n);
for(ll i = 1; i <= n; ++i) scanf("%lld", &a[i]);
pre[1] = a[1];
for(ll i = 2; i <= n; ++i) pre[i] = pre[i - 1] | a[i];
las[n] = a[n];
for(ll i = n - 1; i >= 1; --i) las[i] = las[i + 1] | a[i];
ll ans = 0;
for(ll i = 1; i <= n; ++i)
ans = max(ans, pre[i - 1] | las[i + 1]);
printf("%lld\n", ans);
return 0;
}
1617.HR的双十一[枚举 + 快速幂 + 逆元]
出题人:lzw \quad 验题人:lhr
题目大意
\quad 嗯。
分析
\quad 枚举 i i i 表示第 i i i 天后 LHR 喵币总数 ≥ M \geq M ≥M 且 第 i − 1 i - 1 i−1 天后 LHR 喵币总数 < M \lt M <M,那么该情况的收益为 ∑ j = i n 1 = ( n − i + 1 ) ( i + n ) 2 \sum_{j=i}^n{1} = \frac{(n - i + 1)(i + n)}{2} ∑j=in1=2(n−i+1)(i+n),发生的概率为 C i − 1 ⌈ M x ⌉ − 1 p ⌈ M x ⌉ ( 1 − p ) i − ⌈ M x ⌉ C_{i - 1}^{\lceil{\frac{M}{x}}\rceil - 1} p^{\lceil{\frac{M}{x}}\rceil}(1-p)^{i - \lceil{\frac{M}{x}}\rceil} Ci−1⌈xM⌉−1p⌈xM⌉(1−p)i−⌈xM⌉.
\quad
小坑点:1. 求
p
p
p 的时候需要求
100
100
100 在模
998244353
998244353
998244353 的逆元
\quad\quad\quad\quad
2. 特判
x
=
0
x=0
x=0 和
k
=
0
k = 0
k=0 的情况
\quad 时间复杂度: O ( n l o g ⌈ m x ⌉ ) O(n log\lceil \frac{m}{x} \rceil) O(nlog⌈xm⌉),再用力一点能优化到 O ( n ) O(n) O(n).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e3;
const int N = (int)1e5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)998244353;
int n, x, m, p;
ll c[M + 5][M + 5];
void init()
{
c[0][0] = 1;
for(int i = 1; i <= M; ++i)
{
c[i][0] = 1;
for(int j = 1; j <= i; ++j) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
ll quick(ll a, ll b, ll p = mod)
{
ll s = 1;
while(b)
{
if(b & 1) s = s * a % mod;
a = a * a % mod;
b >>= 1;
}
return s;
}
ll inv(ll n, ll p = mod)
{
return quick(n, p - 2, p);
}
void work()
{
scanf("%d %d %d %d", &n, &x, &m, &p);
p = p * inv(100) % mod;
int q = ((1 - p) % mod + mod) % mod;
ll ans = 0, cur;
if(x == 0)
{
if(m == 0) printf("%lld\n", 1ll * n * (n + 1) / 2 % mod);
else printf("0\n");
return;
}
int k = (m + x - 1) / x;
if(k == 0)
{
printf("%lld\n", 1ll * n * (n + 1) / 2 % mod);
return;
}
for(int i = k; i <= n; ++i)
{
cur = 1ll * (n - i + 1) * (i + n) / 2 % mod;
cur = cur * c[i - 1][k - 1] % mod * quick(p, k) % mod * quick(q, i - k) % mod;
ans = (ans + cur) % mod;
}
printf("%lld\n", ans);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
init();
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1618.The Guo[思维]
出题人:lzw \quad 验题人:lhr、wx
题目大意
\quad 啊。
分析
\quad 不难想到,如果初始地图所有的锅连在一起,那么最小花费为所有锅的和(一次全部修完,不留给锅精造锅的机会)
\quad 否则你至少需要休息一次。所以不论你如何操作,休息一次之后所有的点上都有锅,那么第二次修锅时就可以把所有锅清除掉。
\quad 时间复杂度: O ( n m ) O(nm) O(nm).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e3;
const int N = (int)5e3;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 7;
int read()
{
int x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
int n, m;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
vector<vector<int> > mp;
vector<vector<bool> > vis;
struct node
{
int x, y;
};
queue<node> q;
void bfs(int x, int y)
{
node u, v;
vis[u.x = x][u.y = y] = 1;
q.push(u);
while(!q.empty())
{
u = q.front(); q.pop();
for(int i = 0; i < 4; ++i)
{
v.x = u.x + dx[i], v.y = u.y + dy[i];
if(v.x >= 1 && v.x <= n && v.y >= 1 && v.y <= m && !vis[v.x][v.y] && mp[v.x][v.y])
{
vis[v.x][v.y] = 1;
q.push(v);
}
}
}
}
void work()
{
scanf("%d %d", &n, &m);
mp.resize(n + 1); vis.resize(n + 1);
for(int i = 0; i <= n; ++i) mp[i].resize(m + 1), vis[i].resize(m + 1);
for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) mp[i][j] = read();
int zero = 0; ll sum = 0; for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) zero += !mp[i][j], sum += mp[i][j];
int blocks = 0; for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) if(!vis[i][j] && mp[i][j]) bfs(i, j), ++blocks;
if(blocks == 1) printf("%lld\n", sum);
else printf("%lld\n", sum + 1 + zero);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1619.The Super Guo[DFS + 贪心]
出题人:lhr \quad 验题人:syh、ymf、lzw、wx
题目大意
\quad 呀。
分析
\quad 显然,每次选取一个极大连通块是最优的(走到不能走为止),那么问题就变成了如何安排极大连通块的选择顺序,使用临项交换法可知贪心策略就是:优先选择格点数最多的连通块。
\quad 时间复杂度: O ( n m × l o g ( n m ) ) O(nm \times log(nm)) O(nm×log(nm)).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e5;
const int N = (int)1e5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)998244353;
int n, m;
struct node1
{
int x, y;
};
struct node2
{
ll sum;
int cnt;
};
vector<vector<int> > mp;
vector<vector<int> > vis;
vector<node2> block;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int read()
{
int f = 1, x = 0;
char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
queue<node1> q;
void bfs(int x, int y)
{
node1 u, v;
u.x = x, u.y = y;
q.push(u); vis[u.x][u.y] = 1;
int cnt = 0; ll sum = 0;
while(!q.empty())
{
u = q.front(); q.pop();
++cnt, sum += mp[u.x][u.y];
for(int i = 0; i < 4; ++i)
{
v.x = u.x + dx[i], v.y = u.y + dy[i];
if(v.x < 1 || v.x > n || v.y < 1 || v.y > m || !mp[v.x][v.y] || vis[v.x][v.y]) continue;
vis[v.x][v.y] = 1;
q.push(v);
}
}
node2 tmp;
tmp.cnt = cnt, tmp.sum = sum;
block.push_back(tmp);
}
bool cmp(node2 a, node2 b)
{
return a.cnt > b.cnt;
}
void work()
{
n = read(); m = read();
mp.resize(n + 1); vis.resize(n + 1);
for(int i = 1; i <= n; ++i)
{
mp[i].resize(m + 1); vis[i].resize(m + 1);
for(int j = 1; j <= m; ++j) mp[i][j] = read();
}
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
if(mp[i][j] && !vis[i][j])
{
bfs(i, j);
}
}
}
sort(block.begin(), block.end(), cmp);
int sz = block.size();
ll ans = 0;
for(int i = 0; i < sz; ++i)
{
ans += block[i].sum + 1ll * i * block[i].cnt;
}
printf("%lld\n", ans);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1620.锅精精学数学[组合数学 + 分类讨论]
出题人:ryc \quad 验题人:lhr、lzw
题目大意
\quad 给定整数n,请你求出n的所有合数因子的乘积,由于结果可能过大,请对结果取模998244353。
分析
\quad 由唯一分解定理,将 n n n 表示为 n = p 1 c 1 p 2 c 2 ⋯ p k c k n = p_1^{c_1}p_2^{c_2}\cdots p_k^{c_k} n=p1c1p2c2⋯pkck.
\quad 记 τ ( n ) \tau(n) τ(n) 为 n n n 的正约数的个数,根据乘法原理有 τ ( n ) = ( c 1 + 1 ) ( c 2 + 1 ) ⋯ ( c k + 1 ) \tau(n) = (c_{1} + 1)(c_{2} + 1)\cdots(c_{k} + 1) τ(n)=(c1+1)(c2+1)⋯(ck+1).
\quad 记 π ( n ) \pi(n) π(n) 为 n n n 的正约数的乘积,可以用力求得 π ( n ) = n τ ( n ) 2 \pi(n) = n^{\frac{\tau(n)}{2}} π(n)=n2τ(n).
\quad 然而题目所求为 n n n 的合数因子的乘积,所以答案为 π ( n ) p 1 p 2 ⋯ p k \frac{\pi(n)}{p_1p_2 \cdots p_k} p1p2⋯pkπ(n).
\quad 小细节: π ( n ) = n τ ( n ) 2 \pi(n) = n^{\frac{\tau(n)}{2}} π(n)=n2τ(n) 中 τ ( n ) \tau(n) τ(n) 可能为奇数,此时不能直接除以 2 2 2。由于 τ ( n ) \tau(n) τ(n) 为奇数,即 ( c 1 + 1 ) ( c 2 + 1 ) ⋯ ( c k + 1 ) (c_{1} + 1)(c_{2} + 1)\cdots(c_{k} + 1) (c1+1)(c2+1)⋯(ck+1) 为奇数,可知 c 1 , c 2 , ⋯ , c k c_1,c_2,\cdots,c_k c1,c2,⋯,ck 都是偶数,即 n n n 为完全平方数,此时 n 1 2 n^{\frac{1}{2}} n21 为整数,所以 π ( n ) \pi(n) π(n) 可表示为 ( n 1 2 ) τ ( n ) (n^{\frac{1}{2}})^{\tau(n)} (n21)τ(n).
\quad 小坑点:特判 n % 998244353 = 0 n \% 998244353 = 0 n%998244353=0 的情况.
\quad 时间复杂度: O ( n + l o g ( n ) l o g ( 998244353 ) ) O(\sqrt{n} +log(n) log(998244353)) O(n+log(n)log(998244353)).
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e7;
const int N = (int)1e5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)998244353;
bool is_prime[M + 5];
int cnt, prime[M / 10 + 5];
int m;
struct node
{
ll p; int c;
node(ll _p = 0, int _c = 0): p(_p), c(_c){}
}v[100];
void init()
{
memset(is_prime, 1, sizeof(is_prime));
cnt = is_prime[0] = is_prime[1] = 0;
for(int i = 2; i <= M; ++i)
{
if(is_prime[i]) prime[++cnt] = i;
for(int j = 1; j <= cnt && i * prime[j] <= M; ++j)
{
is_prime[i * prime[j]] = 0;
if(i % prime[j] == 0) break;
}
}
}
void divide(ll n)
{
m = 0;
for(int i = 1; i <= cnt && 1ll * prime[i] * prime[i] <= n; ++i)
{
if(n % prime[i] == 0)
{
ll c = 0;
while(n % prime[i] == 0) ++c, n /= prime[i];
v[m++] = node(prime[i], c);
}
}
if(n > 1) v[m++] = node(n, 1);
}
ll quick(ll a, ll b, ll p = mod)
{
ll s = 1;
while(b)
{
if(b & 1) s = s * a % p;
a = a * a % p;
b >>= 1;
}
return s;
}
ll inv(ll n, ll p = mod)
{
return quick(n, p - 2, p);
}
void work(ll n)
{
if(n == 998244353)
{
printf("1\n");
return;
}
if(n % 998244353 == 0)
{
printf("0\n");
return;
}
divide(n);
ll k = 1;
for(int i = 0; i < m; ++i) k *= v[i].c + 1;
ll sq = (ll)(sqrt(n) + eps);
if(sq * sq == n) n = sq;
else k /= 2;
ll ans = quick(n % mod, k);
for(int i = 0; i < m; ++i) ans = ans * inv(v[i].p % mod) % mod;
printf("%lld\n", ans);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
init();
ll n; while(~scanf("%lld", &n)) work(n);
// work();
// int T; scanf("%d", &T);
// while(T--) work();
return 0;
}
1621.加密通话[思维]
出题人:zlk \quad 验题人:lzw
题目大意
\quad 呱。
分析
\quad 按照二进制位分析 So Easy.
\quad 只需要在题目所给代码的基础上加 3 3 3 行即可 AC.
\quad 时间复杂度: O ( n 2 n ) O(n2^n) O(n2n)
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e3;
const int N = (int)5e3;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 7;
char s[M + 5];
void work()
{
scanf("%s", s + 1);
int n = (int)(log2(strlen(s + 1)) + eps) + 1;
int p = 0;
for(int i = 0; i < n; ++i)
{
int t = 0;
for(int j = 1; j <= (1<<n) - 1; ++j)
{
if((1<<i)&j) t ^= s[j];
}
if(t) p |= (1<<i);
}
s[p] ^= 1;
printf("%s\n", s + 1);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// work();
int T; scanf("%d", &T);
while(T--) work();
return 0;
}
1624.新型冠状病毒[组合数学]
出题人:lhr \quad 验题人:lzw
题目大意
\quad 哞。
分析
\quad
显然 答案为
C
t
x
C
t
−
x
y
C_t^xC_{t-x}^y
CtxCt−xy.
\quad 时间复杂度: O ( 1 0 7 + T l o g ( 998244353 ) ) O(10^7 + Tlog(998244353)) O(107+Tlog(998244353))
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)1e7;
const int N = (int)1e5;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)998244353;
ll fac[M + 5];
ll quick(ll a, ll b, ll p = mod)
{
ll s = 1;
while(b)
{
if(b & 1) s = s * a % p;
a = a * a % p;
b >>= 1;
}
return s;
}
ll inv(ll n, ll p = mod)
{
return quick(n, p - 2, p);
}
ll c(int n, int m)
{
return fac[n] * inv(fac[m]) % mod * inv(fac[n - m]) % mod;
}
void work()
{
int x, y, t;
scanf("%d %d %d", &x, &y, &t);
if(x > t || y > t - x) {printf("0\n"); return;}
ll ans = 1;
ans = ans * c(t, x) % mod;
ans = ans * c(t - x, y) % mod;
printf("%lld\n", ans);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// work();
fac[0] = 1; for(int i = 1; i <= M; ++i) fac[i] = fac[i - 1] * i % mod;
int T; scanf("%d", &T);
while(T--) work();
return 0;
}
吐槽
- 办比赛真累,以后不想搞了(真香)。
- 这群人怎么回事,学了一个多月,除了暴力啥也不会(其实暴力也不会)?
下周不得被齐工大锤爆
END
所以说,知道自己的真实实力最重要,不要因为一时的失败就觉得自己不行。
一定要多试几次你才会知道,自己真的不行。