标签:要求 字典序 name 超过 直接 circle 存在 最短路 一个
签到题, 要求第一位维单增, 第二维变化比第一维慢, 直接模拟即可
每个人有一些财富, 财富值超过x的人称为富人, 由于实行共产主义, 你可以将某些人的财产重新分配使得富人最多
直接按财富值排序, 从大到小加入富人集合, 如果当前富人集合财富平均值小于x就break掉
有一圈怪物, 它们每个都有一些生命值\(a_i\), 爆炸时对第\((i\%n)+1\)个怪物造成\(b_i\)的伤害, 你每次可以打一滴血, 问最少打几次
首先贪心的想到从一个点开始,肯定是连着打下去的, 也就是打怪顺序类似这样\(i,i+1,i+2,i+3\), 只有这样才可以利用用上每个怪物爆炸所产生的价值, 所以我们倍长, 断环成链, \(c_i=(i-1)爆炸后自己还需打的次数 = a_{i}-b_{i-1}\), 对其记一下前缀和, 枚举第一个打哪个怪物即可
const int N = 1000050;
ll a[N], b[N], sum[N], T, n;
int main() {
read(T);
while (T--) {
read(n);
for (int i = 1;i <= n; i++)
read(a[i]), read(b[i]),
a[i+n] = a[i], b[i+n] = b[i];
for (int i = 1;i <= 2 * n; i++)
sum[i] = sum[i-1] + max(a[i] - b[i-1], 0ll);
ll ans = a[1] + sum[n] - sum[1];
for (int i = 1;i <= n; i++)
ans = min(a[i] + sum[i+n-1] - sum[i], ans);
printf ("%lld\n", ans);
}
return 0;
}
给一个完全有向图, 也就是每两个不同的点都有两条有向边, 从1点开始走, 每条边只可遍历一次, 求一种方案使遍历点序列的字典序最小\(1->2->1->3->1->4 =1 2 1 3 1 4\)
模拟一下可以发现, 先从1点到其他节点然后立刻从其他节点回来, 但到n号节点时则不能回来因为回来就无路可走, n号节点只能走向2号节点, 2号节点在依次走向\(2,3,4...\)号节点并返回, 到n号节点时走向3号节点, 发现就是从小到大把这个点所有的连边都走尽最后到达n号节点并进入下一个点的轮回, 要注意的是最后n点要回到1点
ll T, n, l, r;
int main() {
read(T);
while (T--) {
read(n), read(l), read(r);
if (n == 2) {
}
ll sum = 0, pre = 0;
for (int i = 1;i < n; i++) {
sum += (n - i) * 2;
if (l < sum) {
ll t = l - pre;
ll x = (t & 1) ? i : (t / 2) + i, y = (t / 2) + i;
while (l < sum && l <= r) {
printf ("%lld ", x);
x == i ? y++, x = y : x = i;
l++;
}
}
if (l == sum && l <= r) printf ("%lld ", n), l++;
pre = sum;
if (l > r) break;
}
if (l <= r) printf ("1");
puts("");
}
return 0;
}
给定一个正整数D, 以此建图
求q组\((1\le q \le 3\cdot10^5)\)(a, b)的最短路径个数
大力猜结论题
首先发现从x和y的边权是什么呢, 设\(k=\frac xy\), 则边权为while (y % k == 0) y /= k
之后y的因子个数, 更严谨的讲\(y = k^{a_1}p_1^{a_2}...p_n^{a_{n+1}}\), 在x中却不再y中只可能是\(k^{a_1+1}*X\)的形式, k要取到最高次才可以产生贡献, 可以模拟一下.
从y走到x的本质是什么呢, 就是加一个质因子进来并付出一定代价
然后两个数肯定是向上跳到它们的lcm停止, 否则肯定不优, 而且我们发现从x到lcm添加质因子的顺序不同, 路径长度是一样的, 这代表着我们只用记录从x到lcm有多少添加质因子的方法再乘上y的方案数就是答案
求解添加质因数方案数时可以用组合数转移, 当前集合方案数=之前集合方案数*C(当前集合大小, 新增质因子个数), 也可以用其他方法,不再赘述
#include <queue>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#define MP make_pair
#define ll long long
#define fi first
#define se second
using namespace std;
template <typename T>
void read(T &x) {
x = 0; bool f = 0;
char c = getchar();
for (;!isdigit(c);c=getchar()) if (c==‘-‘) f=1;
for (;isdigit(c);c=getchar()) x=x*10+(c^48);
if (f) x=-x;
}
template <typename T>
inline void Mx(T &x, T y) { x < y && (x = y); }
template <typename T>
inline void Mn(T &x, T y) { x > y && (x = y); }
const int P = 998244353;
ll d, a, b, n;
map<ll, int> mp;
ll y[500], cnt;
ll tmp[50], jie[500], inv[500];
inline ll C(ll n, ll m) {
return jie[n] * inv[n-m] % P * inv[m] % P;
}
int main() {
read(d), read(n); if (d % 2 == 0) y[++cnt] = 2;
while (d % 2 == 0) d /= 2;
for (ll i = 3;i * i <= d; i += 2) {
if (d % i) continue;
y[++cnt] = i;
while (d % i == 0) d /= i;
}
if (d != 1) y[++cnt] = d;
jie[0] = 1; for (int i = 1;i <= 100; i++) jie[i] = jie[i-1] * i % P;
inv[0] = inv[1] = 1;
for (int i = 2;i <= 100; i++) inv[i] = (P - P / i) * inv[P % i] % P;
for (int i = 2;i <= 100; i++) inv[i] = inv[i-1] * inv[i] % P;
while (n--) {
read(a), read(b);
ll aa = 0, bb = 0, s1 = 1;
for (int i = 1;i <= cnt; i++) {
int ta = 0, tb = 0;
while (a % y[i] == 0) a /= y[i], ta++;
while (b % y[i] == 0) b /= y[i], tb++;
int tt = max(ta, tb);
aa += tt - ta, bb += tt - tb;
s1 = (s1 * C(aa, tt - ta) % P * C(bb, tt - tb)) % P;
}
printf ("%lld\n", s1 % P);
}
return 0;
}
Educational Codeforces Round 85 (Rated for Div. 2)
标签:要求 字典序 name 超过 直接 circle 存在 最短路 一个
原文地址:https://www.cnblogs.com/Hs-black/p/12677650.html