牛客练习赛27(A,C,E题解)

A纸牌
最优解为
a − b 2 = n 2 , b − a = n 2 , a − b = 0 a-\frac{b}{2}=\frac{n}{2},b-a=\frac{n}{2},a-b=0 a2b=2n,ba=2n,ab=0(n is even)
a − b + 1 2 = n − 1 2 , b − a = n + 1 2 , a − n − 1 2 = 0 a-\frac{b+1}{2}=\frac{n-1}{2},b-a=\frac{n+1}{2},a-\frac{n-1}{2}=0 a2b+1=2n1,ba=2n+1,a2n1=0(n is odd)
最终 a + b = ⌊ n + 1 2 ⌋ a+b=\lfloor \frac{n+1}{2}\rfloor a+b=2n+1

#include <cstdio>
using namespace std;
int main() {
	int n;
	scanf("%d", &n);
	printf("%d\n", (n + 1) / 2);
	return 0;
}

C水图
可以发现每条边都要被走两次(除了最后一条路径上的边)
于是题目转换为求从 x x x出发最长的一条边的 l e n m a x len_{max} lenmax
最终答案为 a n s = 2 × ∑ w − l e n m a x ans=2\times \sum w-len_{max} ans=2×wlenmax

#include <cstdio>
#include <algorithm>
#define N 50010

typedef long long LL;
using namespace std;

int cnt, lst[N];
LL del;

struct Node{
	int to, nxt;
	LL len;
}e[N << 1];

inline void add(int u, int v, LL w) {
	e[++cnt].to = v;
	e[cnt].nxt = lst[u];
	e[cnt].len = w;
	lst[u] = cnt;
}

void dfs(int x, int fa, LL sum) {
	del = max(del, sum);
	for (int i = lst[x]; i; i = e[i].nxt) {
		int son = e[i].to;
		if (son == fa) continue;
		dfs(son, x, sum + e[i].len);
	}
}

int main() {
	int n, x;
	scanf("%d%d", &n, &x);
	LL ans = 0;
	for (int i = 1; i < n; ++i) {
		int u, v;
		LL w;
		scanf("%d%d%lld", &u, &v, &w);
		add(u, v, w);
		add(v, u, w);
		ans += w;
	}
	ans *= 2;
	dfs(x, x, 0);
	ans -= del;
	printf("%lld\n", ans);
}

E欧拉
别的不多说了,直接搞式子

n = p 1 k 1 p 2 k 2 p 3 k 3 . . . p r k r ( p i ≠ p j ) n=p_1^{k_1}p_2^{k_2}p_3^{k_3}...p_r^{k_r}(p_i \neq p_j) n=p1k1p2k2p3k3...prkr(pi̸=pj)
q t ∣ x ( t &gt; 1 ) → μ ( x ) = 0 q^t|x(t&gt;1) \to \mu(x)=0 qtx(t>1)μ(x)=0
f ( n ) = ∑ d ∣ n d k μ ( n d ) = ( p 1 k 1 − 1 p 2 k 2 − 1 p 3 k 3 − 1 . . . p r k r − 1 ) k × f ( p 1 p 2 p 3 . . . p r ) f(n)=\sum_{d|n}d^k \mu(\frac{n}{d})=(p_1^{k_1-1}p_2^{k_2-1}p_3^{k_3-1}...p_r^{k_r-1})^k \times f(p_1p_2p_3...p_r) f(n)=dndkμ(dn)=(p1k11p2k21p3k31...prkr1)k×f(p1p2p3...pr)
∵ ϕ ( p 1 p 2 p 3 . . . p r ) = ( p 1 − 1 ) ( p 2 − 1 ) ( p 3 − 1 ) . . . ( p r − 1 ) \because \phi (p_1p_2p_3...p_r)=(p_1-1)(p_2-1)(p_3-1)...(p_r-1) ϕ(p1p2p3...pr)=(p11)(p21)(p31)...(pr1)
∴ f ( p 1 p 2 p 3 . . . p n ) = ( p 1 k − 1 ) ( p 2 k − 1 ) ( p 3 k − 1 ) . . . ( p r k − 1 ) \therefore f(p_1p_2p_3...p_n)=(p_1^k-1)(p_2^k-1)(p_3^k-1)...(p_r^k-1) f(p1p2p3...pn)=(p1k1)(p2k1)(p3k1)...(prk1)
综上
f ( n ) = ( p 1 k 1 − 1 p 2 k 2 − 1 p 3 k 3 − 1 . . . p r k r − 1 ) k × ( p 1 k − 1 ) ( p 2 k − 1 ) ( p 3 k − 1 ) . . . ( p r k − 1 ) f(n)=(p_1^{k_1-1}p_2^{k_2-1}p_3^{k_3-1}...p_r^{k_r-1})^k \times (p_1^k-1)(p_2^k-1)(p_3^k-1)...(p_r^k-1) f(n)=(p1k11p2k21p3k31...prkr1)k×(p1k1)(p2k1)(p3k1)...(prk1)
由于时间限制,预处理出了所有的质数和它们的 k k k次幂

#include <cstdio>
#define MOD 998244353
#define N 5000010

typedef long long LL;
using namespace std;

LL pr[N], kp[N], f[N];
int cnt;

int qui_pow(LL x, int y) {
	if (y == 1) return x;
	LL t = qui_pow(x, y / 2);
	if (y % 2 == 0) return t * t % MOD;
	else return t * t % MOD * x % MOD;
}

int main() {
	int m, k;
	scanf("%d%d", &m, &k);
	for (int i = 2; i * i < N; ++i) {
		if (!f[i]) {
			for (int j = 2; i * j < N; ++j) {
				f[i * j] = 1;
			}
		}
	}
	for (int i = 2; i < N; ++i) {
		if (!f[i]) {
			pr[++cnt] = i;
			kp[cnt] = qui_pow(i, k);
		}
	}
	for (int i = 1; i <= m; ++i) {
		LL n, ans = 1, all = 1;
		scanf("%lld", &n);
		for (int i = 1; f[n]; ++i) {
			if (n % pr[i] == 0) {
				n /= pr[i];
				ans = ans * (kp[i] - 1) % MOD;
				while (n % pr[i] == 0) {
					all = all * pr[i] % MOD;
					n /= pr[i];
				}
			}
		}
		if (n > 1) {
			ans = ans * (qui_pow(n, k) - 1) % MOD;
		}
		ans = ans * qui_pow(all, k) % MOD;
		if (ans < 0) ans += MOD;
		printf("%lld\n", ans);
	}
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值