v
個につき、答えに 加算、w
個につき、答えに 加算すれば OK。文字列と for
ループが使えれば簡単。#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
int ans = 0;
cin >> s;
for (int i = 0; i < s.length(); ++i) {
if (s[i] == 'v') { // i 文字目が 'v' なら
++ans; // 1 加算
} else { // そうでないなら (i 文字目が 'w' なら)
ans += 2; // 2 加算
}
}
cout << ans;
return 0;
}
v
の個数) + (w
の個数) × で解いたけど、(文字列の長さ) + (w
の個数) で解いたほうが賢かったかも?#include <bits/stdc++.h>
using namespace std;
int main() {
string s, t;
cin >> s >> t;
// 0-indexed 版
for (int i = 0; i + t.length() <= s.length(); ++i) {
bool flag = true; // i 文字目から (i + |T| - 1) 文字目が T と一致しているか
// 1 文字ずつ一致しているか調べる
for (int j = 0; j < t.length(); ++j) {
if (s[i + j] != t[j]) { // 1 文字でも一致していなければ
flag = false; // 一致していないことが確定
break; // 終了
}
}
if (flag) { // 全部一致していれば
cout << "Yes"; // "Yes" を出力して
return 0; // 終了
}
}
cout << "No"; // どの場合も一致しなければ "No"
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main() {
int h, w;
cin >> h >> w;
// 列でソートしたいので、s[列][行] になるようにする (t も同様)
vector<vector<char>> s(w, vector<char>(h)), t(w, vector<char>(h));
string in; // 入力用
// 入力 (s[列][行] にする)
for (int i = 0; i < h; ++i) {
cin >> in;
for (int j = 0; j < w; ++j) {
s[j][i] = in[j];
}
}
// 入力 (t[列][行] にする)
for (int i = 0; i < h; ++i) {
cin >> in;
for (int j = 0; j < w; ++j) {
t[j][i] = in[j];
}
}
// それぞれソート
sort(s.begin(), s.end());
sort(t.begin(), t.end());
// 一致していれば "Yes"、してなければ "No"
cout << (s == t ? "Yes" : "No");
return 0;
}
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ll a, b;
cin >> a >> b;
// にぶたん
ll ok = 1, ng = a / b + 1; // 区間 (1, a / b + 1) を探索
for (ll mid = (ok + ng) / 2; abs(ok - ng) > 1; mid = (ok + ng) / 2) {
// f(mid) - f(mid - 1) < 0 なら
if (b + (double)a / sqrt(mid) - (double)a / sqrt(mid - 1) < 0)
ok = mid; // mid は条件を満たす
else
ng = mid; // mid は条件を満たさない
}
// 誤差で引っかからないように、小数点以下を適当に長めに出力
printf("%.10lf", (double)a / sqrt(ok) + b * (ok - 1));
return 0;
}
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
int n, m;
cin >> n >> m;
// 0-indexed にして、B_j = 0 を満たす j を考える
vector<int> b(n);
for (int i = 0; i < n; ++i) b[i] = i;
// 操作 i で入れ替わる数字を記録しながら、すべての操作を実行
vector<pair<int, int>> swaped(m); // 操作 i で入れ替わった数字のペア
for (int i = 0, a; i < m; ++i) {
cin >> a;
// 0-indexed にしたので、(a, a + 1) => (a - 1, a)
swaped[i] = {b[a - 1], b[a]}; // 入れ替わる数字を記録
swap(b[a - 1], b[a]); // 入れ替え
}
vector<int> inv(n); // 数字 i がある位置を求める
for (int i = 0; i < n; ++i) {
inv[b[i]] = i;
}
// S_i を求める
for (int i = 0; i < m; ++i) {
// 入れ替えた数字のどちらかが 1 なら、
// 1 ではないほうの数字の位置が、操作 i を抜いたときの 1 の位置
// そうでないなら、
// 操作 i を抜いても抜かなくても 1 の位置は変わらない
// ※ 0-indexed にしたので、実際は、1 ではなく 0
// 位置も最後に 1 加算する
if (!swaped[i].first) {
cout << inv[swaped[i].second] + 1 << '\n';
} else if (!swaped[i].second) {
cout << inv[swaped[i].first] + 1 << '\n';
} else {
cout << inv[0] + 1 << '\n';
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
// Union-Find 用のクラス
class UnionFind {
vector<int> p;
public:
UnionFind(int n) : p(n, -1) {} // n は要素数
void unite(int x, int y) { // union 関数
x = find(x);
y = find(y);
if (x == y) return;
if (p[x] < p[y]) {
p[x] += p[y];
p[y] = x;
} else {
p[y] += p[x];
p[x] = y;
}
return;
}
int find(int x) { // find 関数 (代表を返す)
if (p[x] < 0) return x;
while (p[p[x]] >= 0) {
p[x] = p[p[x]];
x = p[x];
if (p[x] < 0) return x;
}
return p[x];
}
// 今回は使わない
bool isSame(int x, int y) { return find(x) == find(y); }
// 今回は使わない
int size(int x) { return -p[find(x)]; }
};
int main() {
int n, q;
cin >> n >> q;
// 箱に含まれるボールのうちの 1 つを保持する (空なら -1)
vector<int> box(n + 1);
// 代表から箱を割り出す用
vector<int> inv(n + q + 1);
// 最初は箱 i にボール i のみが入っているので、
// 箱 i に含まれるボールのうちの 1 つはボール i のみで、
// ボール i はそれぞれ箱 i の代表
for (int i = 1; i <= n; ++i) box[i] = i, inv[i] = i;
int ball = n; // ボールの個数
UnionFind u(n + q + 1); // ボールは最大で (n + q) 個くらい
for (int i = 0, t, x, y; i < q; ++i) {
cin >> t >> x;
if (t == 1) { // タイプ 1
cin >> y; // 追加で y を受け取る
if (box[y] == -1) continue; // 箱 y が空なら何もしない
if (box[x] == -1) { // 箱 x が空なら
// 箱 y の要素は箱 x の要素になる
box[x] = box[y];
// 代表が変わったので新たな代表が箱 x を指すようにする
inv[u.find(box[x])] = x;
} else { // 両方中身があるなら
// 箱 x と箱 y を union
u.unite(box[x], box[y]);
// 代表が変わった可能性があるので新たな代表が箱 x を指すようにする
inv[u.find(box[x])] = x;
}
box[y] = -1; // 箱 y は空にする
} else if (t == 2) { // タイプ 2
++ball; // ボールの個数を加算
if (box[x] == -1) { // 箱 x が空なら
// ボール ball は箱 x の要素になる
box[x] = ball;
// 代表が変わったので新たな代表が箱 x を指すようにする
inv[u.find(box[x])] = x;
} else { // 空でないなら
// 箱 x とボール ball を union
u.unite(box[x], ball);
// 代表が変わった可能性があるので新たな代表が箱 x を指すようにする
inv[u.find(ball)] = x;
}
} else { // タイプ 3
// x があるグループの代表から箱を割り出して出力
cout << inv[u.find(x)] << '\n';
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// 法 mod での累乗
long long pow(long long n, long long m, long long mod) {
long long ans = 1;
while (m) {
if (m & 1) ans = ans * n % mod;
n = n * n % mod;
m >>= 1;
}
return ans;
}
int main() {
int n, k, c;
const int mod = 998244353;
cin >> n >> k >> c;
// K = 2 なら C の N 乗が答え
if (k == 2) {
cout << pow(c, n, mod);
return 0;
}
vector<ll> dp1(n + 1), dp2cis(n + 1), dp2trans(n + 1);
// 以下、式のとおり
dp1[1] = c % mod;
// K - 1 以下
for (int i = 2; i <= k - 1; ++i) {
dp1[i] = dp1[i - 1]; // dp1[i] = c % mod;
dp2cis[i] = (dp2cis[i - 1] + dp2trans[i - 1]) % mod;
dp2trans[i] = (dp1[i - 1] * (c - 1) + dp2cis[i - 1] + dp2trans[i - 1]) % mod;
}
// K 以上
for (int i = k; i <= n; ++i) {
dp1[i] = (dp1[i - k + 1] * c + (dp2cis[i - k + 1] + dp2trans[i - k + 1]) * 2) % mod;
dp2cis[i] = (dp2cis[i - 1] + dp2trans[i - 1] + (mod - dp2trans[i - k + 2])) % mod;
dp2trans[i] = (dp1[i - 1] * (c - 1) + dp2cis[i - 1] + dp2trans[i - 1]) % mod;
}
cout << (dp1[n] + dp2cis[n] + dp2trans[n]) % mod;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// Lucas の定理を用いた二項係数の計算
// fact は前計算した階乗、inv は前計算した階乗の逆数
ll lucas(ll n, ll k, const ll mod, const vector<ll> &fact, const vector<ll> &inv) {
if (n < k) return 0;
ll ret = 1;
while (n) {
ll ni = n % mod;
ll ki = k % mod;
if (ni < ki) return 0;
ret *= (fact[ni] * (inv[ki] * inv[ni - ki] % mod)) % mod;
ret %= mod;
n /= mod;
k /= mod;
}
return ret;
}
// 法 mod での累乗 (逆数計算用)
long long pow(long long n, long long m, long long mod) {
long long ans = 1;
while (m) {
if (m & 1) ans = ans * n % mod;
n = n * n % mod;
m >>= 1;
}
return ans;
}
int main() {
ll n, m;
ll ans = 0;
const int mod = 200003;
cin >> n >> m;
// 階乗と階乗の逆数
vector<ll> fact(mod), inv(mod);
// 階乗の計算
fact[0] = 1;
for (int i = 1; i < mod; ++i) fact[i] = fact[i - 1] * i % mod;
// 階乗の逆数の計算
inv[mod - 1] = pow(fact[mod - 1], mod - 2, mod);
for (int i = mod - 1; i > 0; --i) inv[i - 1] = inv[i] * i % mod;
// 以下、式のとおり
// e_k <= M - N (k >= 0)
for (ll i = 0; i * (3 * i - 1) / 2 <= m - n; ++i) {
ll ek = i * (3 * i - 1) / 2;
ans += (i & 1 ? mod - 1 : 1) * lucas(m + n - ek - 1, 2 * n - 1, mod, fact, inv);
ans %= mod;
}
// e_k <= M - N (k < 0)
for (ll i = -1; i * (3 * i - 1) / 2 <= m - n; --i) {
ll ek = i * (3 * i - 1) / 2;
ans += (i & 1 ? mod - 1 : 1) * lucas(m + n - ek - 1, 2 * n - 1, mod, fact, inv);
ans %= mod;
}
cout << ans;
return 0;
}