当前位置: 首页 > news >正文

P3330 [ZJOI2011] 看电影

思路

第一眼看去好像并没有什么思路,于是我们打了一个表,
\(n = 2\) 时,当 \(k\) 变化时,答案如表所示

n\ k 1 2 3 4
1 (1, 1) (2, 2) (3, 3) (4, 4)
2 (0, 1) (3, 4) (15, 16) (24, 25)
3 (0, 1) (0, 1) (16, 27) (108, 125)
4 (0, 1) (0, 1) (0, 1) (125, 256)

于是我们发现在 \(k\) 相同时,\(n\) 增大时的答案有规律,我们发现相邻两项的关系是: 下一项的第二项乘\(\frac{k - n}{k}\) 为上一项的第一项, 然后发现 \(n = k\) 时也是有规律的,两项关系是:第上一项的第二项乘 \(\frac{(k + 1) ^ {n - 1}}{k^{n - 1}}\) 等于这一项的第一项,然后通过归纳总结法得出通项公式:

\[ans = \frac{(k + 1) ^ {n - 1} \times (k - n + 1)}{k ^ n} \]

由于 \(k ^ n\) 很大,所以高精度
\(C++\) \(AC\) \(Code:\)

#include <bits/stdc++.h>
using namespace std;const int MAXN = 2e3;
const int MAX_PRIME = 210;
int t;
int n, k;
int a[MAX_PRIME], b[MAX_PRIME];
int low[MAX_PRIME];
bitset<MAX_PRIME> not_prime;
vector<int> prime;class number {
public:int val[MAX_PRIME];number() {memset(val, 0, sizeof(val));}number operator*(const number &b) const {number res;for (int i = 0; i < MAX_PRIME; ++i)res.val[i] = val[i] + b.val[i];return res;}
} A, B;class number2 {
public:int val[MAXN];int len;number2() {memset(val, 0, sizeof(val));len = 1;}number2 operator*(const number2 &b) const {number2 res;for (int i = 1; i <= len; ++i) {for (int j = 1; j <= b.len; ++j) {res.val[i + j - 1] += val[i] * b.val[j];}}res.len = len + b.len;for (int i = 1; i <= res.len; ++i) {res.val[i + 1] += res.val[i] / 10;res.val[i] %= 10;}while (res.len > 1 && res.val[res.len] == 0) {res.len--;}return res;}
};number2 change2(int x) {number2 res;if (x == 0) {res.val[1] = 0;res.len = 1;return res;}res.len = 0;while (x > 0) {res.val[++res.len] = x % 10;x /= 10;}return res;
}number2 qpow(number2 base, int x) {number2 res;res.val[1] = 1;while (x > 0) {if (x & 1) {res = res * base;}base = base * base;x >>= 1;}return res;
}void print(number X) {number2 res;res.val[1] = 1;for (int i = 2; i < MAX_PRIME; ++i) {if (X.val[i] > 0) {res = res * qpow(change2(i), X.val[i]);}}for (int i = res.len; i >= 1; --i) {cout << res.val[i];}cout << ' ';
}void init() {for (int i = 2; i < MAX_PRIME; ++i) {if (!not_prime[i]) {prime.push_back(i);low[i] = i;}for (auto pri : prime) {if (pri * i >= MAX_PRIME)break;not_prime[pri * i] = true;low[pri * i] = pri;if (i % pri == 0)break;}}
}number change(int x) {number res;for (auto pri : prime) {while (x % pri == 0) {res.val[pri]++;x /= pri;}}return res;
}number pow_(number base, int x) {number res;for (int i = 0; i < MAX_PRIME; ++i) {res.val[i] = base.val[i] * x;}return res;
}void print_() {print(A);print(B);cout << '\n';
}void solve() {cin >> n >> k;if (n > k) {cout << "0 1\n";return;}number k_ = change(k);number k_plus_1 = change(k + 1);number k_plus_1_jian_n = change(k + 1 - n);A = pow_(k_plus_1, n - 1) * k_plus_1_jian_n;B = pow_(k_, n);for (int i = 2; i < MAX_PRIME; ++i) {int min_val = min(A.val[i], B.val[i]);A.val[i] -= min_val;B.val[i] -= min_val;}print_();
}int main() {
#ifndef DEBUGfreopen("a.in", "r", stdin);freopen("a.out", "w", stdout);
#endifinit();cin >> t;while (t--) {solve();}return 0;
}
http://www.hskmm.com/?act=detail&tid=30372

相关文章:

  • 20232315 2025-2026-1 《网络与系统攻防技术》实验一实验报告
  • 地址
  • CSP-S 2025 提高级模拟赛 Day6 复盘 B.连通子图
  • 新手村程序
  • Android Camera openCamera - 教程
  • 信号与系统
  • 大作业第一阶段验收小组集体加5分 -
  • 业务定义与指标体系搭建
  • Linux使用笔记
  • [Vulhub靶机]W1R3S靶机渗透
  • 基于zynq实现一个边缘识别视频流(预学习HLS篇)
  • 咬鼠
  • 10月13日日记
  • 分享一个知乎高赞回答生成AI指令:让技术人也能写出有深度的回答
  • 实用指南:C语言速成秘籍——循环结构(while、do while、for)和跳转语句(break,continue)
  • 描述https的加密过程
  • CSP-S 2025 提高级模拟赛 Day6 复盘 A.选择方案
  • SSL证书批量申请终极指南:一次搞定所有域名
  • npm install creat-vue命令使用报错解决方法
  • PDF转图片工具:基于PyQt5的完整实现与深度解析 - 详解
  • MongoDB安装及使用
  • 从Gemini Robotics看通用机器人的科技路径
  • 张量的基本操作
  • Windows7 隐藏用户
  • 10 月记录
  • 统计学习方法学习Day01
  • gpt-5-codex vs gpt-5
  • Jenkins Share Library开发入门(一)
  • 第十三篇
  • 虚树