AtCoder Beginner Contest 405
数学,优化求和顺序
就是常见的结论题。
\[\left( \sum_{1 \leq i \leq N} A_i \right)^2 = \sum_{1 \leq i \leq N} A_i^2 + 2 \sum_{1 \leq i < j \leq N} A_i A_j
\]
\[S = \sum_{1 \leq i \leq N} A_i
\]
\[Q = \sum_{1 \leq i \leq N} A_i^2 \\
\]
\[\sum_{1 \leq i < j \leq N} A_i A_j = \frac{S^2 - Q}{2}
\]
#include <iostream>
#include <vector>
using namespace std;
long long f(const vector<int>& A) {
long long S = 0;
long long Q = 0;
for (int x : A) {
S += x;
Q += (long long)x * x;
}
return (S * S - Q) / 2;
}
int main() {
int N;
cin >> N;
vector<int> A(N);
for (int i = 0; i < N; i++) {
cin >> A[i];
}
cout << f(A) << endl;
return 0;
}
BFS,模拟
按照题意模拟即可,即将每个 \(E\) 加入队列,然后向四个方向遍历所有点,并且更新方向。
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
//#define int long long
inline int rd(){
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
#define rd rd()
void wt(int x){
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
wt(x / 10);
putchar(x % 10 + '0');
return;
}
void wt(char x){
putchar(x);
}
void wt(int x, char k){
wt(x),putchar(k);
}
namespace Star_F{
const int N = 1005;
int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
char c[N][N], ans[N][N], dir[] = {'v', '^', '>', '<'};
int dis[N][N];
void Main(){
int H, W;
cin >> H >> W;
for (int i = 1; i <= H; i++)
cin >> c[i] + 1;
memset(dis, -1, sizeof(dis));
queue<PII> q;
for (int i = 1; i <= H; i++)
for (int j = 1; j <= W; j++)
if (c[i][j] == 'E')
dis[i][j] = 0,q.push({i, j});
while (!q.empty()){
int x, y;
x = q.front().fi, y = q.front().se;
q.pop();
for (int i = 0; i < 4; i++){
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 1 && nx <= H && ny >= 1 && ny <= W && c[nx][ny] == '.' && dis[nx][ny] == -1){
dis[nx][ny] = dis[x][y] + 1;
ans[nx][ny] = dir[i];
q.push({nx, ny});
}
}
}
for (int i = 1; i <= H; i++){
for (int j = 1; j <= W; j++){
if (c[i][j] == '.')
cout << ans[i][j];
else
cout << c[i][j];
}
cout << endl;
}
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ClockA;
int T=1;
// T=rd;
while(T--) Star_F::Main();
// ClockB;
return 0;
}
数论,组合数学
假设第一个葡萄的位置是 \(i\),那么前 \(i-1\) 个位置由 \(a\) 和苹果、\(b\) 个橘子、\(x = i - 1 - a - b\) 个香蕉组成。后 \(n-i\) 个位置就由 \(c-x\) 个香蕉和剩下的葡萄组成。
前 \(i-1\) 个只需要确定橘子的摆放方案,会发现苹果和香蕉的方案就唯一了(因为苹果必须在香蕉前面)所以方案数就是 \(\binom{i-1}{b}\)。
后 \(n-i\) 个只需要确定香蕉的摆放方案,剩下的就只能摆葡萄了,方案数是 \(\binom{n-i}{c-x}\)。
答案为 \(\binom{i-1}b \times \binom{n-i}{c-x}\)
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
#define int long long
inline int rd(){
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
#define rd rd()
void wt(int x){
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
wt(x / 10);
putchar(x % 10 + '0');
return;
}
void wt(char x){
putchar(x);
}
void wt(int x, char k){
wt(x),putchar(k);
}
namespace Star_F{
const int N = 4e6 + 5, mod = 998244353;
ll fac[N], inv[N];
ll qpow(ll a,ll b){
ll res = 1;
while(b){
if(b&1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void init(){
fac[0] = 1, inv[0] = 1;
for (int i = 1; i < N; i++)
fac[i] = fac[i - 1] * i % mod;
inv[N - 1] = qpow(fac[N - 1], mod - 2);
for (int i = N - 2; i >= 1; i--)
inv[i] = inv[i + 1] * (i + 1) % mod;
}
ll C(ll n,ll m){
if(n<0||m<0)
return 0;
if(m>n)
return 0;
return fac[n] * inv[m] % mod * inv[n - m] % mod;
}
void Main(){
init();
ll a = rd, b = rd, c = rd, d = rd;
ll res = 0, n = a + b + c + d;
for(int i = a+b+1; i <= n - d + 1; i++){
int x = i - 1 - a - b;
res = (res + C(i - 1, b) * C(n - i, c - x) % mod) % mod;
}
cout << res << endl;
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ClockA;
int T=1;
// T=rd;
while(T--) Star_F::Main();
// ClockB;
return 0;
}