[XJOI3529] 左右
题目链接:左右
Description
给你一个s数组,一个t数组,你可以对s数组执行以下两种操作
L 操作:每个数等于其左边的数加上自己
R 操作:每个数等于其右边的数加上自己
第一个数的左边是最后一个数,最后一个数的右边是第一个数
对于每个操作,所有的加法是同时进行的,即(new)s[i] = (old)s[i - 1] + (old)s[i]
现在问你s数组能否变成t数组。
数据范围 \(1\le n\le 50, 1\le s_i, t_i\le 10^{15}\)
Solution
引理:只要确定了\(L\)和\(R\)的次数,无论按什么顺序操作,最终序列都相同。
我们将这个数列视为一个多项式,并以\(0,1,...,n-1\)作为下标,则:
序列为\(a_0,a_1x,a_2x^2,...,a_{n-1}x^{n-1}\)
\(L\)操作等价于这个式子乘以\((1+x)\),指数对\(n\)取模。
\(R\)操作等价于这个式子乘以\((1+x^{n-1})\),指数对\(n\)取模。
我们发现,\(L\)和\(R\)操作的顺序并不影响序列的结果。
那么我们可以暴力枚举\(L\)和\(R\)的次数,并且直接模拟即可。
注意到,因为上限是\(10^{15}\),所以最多只需要\(L\)和\(R\)操作\(log\)次即可。
复杂度 \(O(n^3)\),跑不满。
Code
// Author: wlzhouzhuan
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define rint register int
#define rep(i, l, r) for (rint i = l; i <= r; i++)
#define per(i, l, r) for (rint i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)
inline int read() {
int x = 0, neg = 1; char op = getchar();
while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
return neg * x;
}
inline void print(int x) {
if (x < 0) { putchar('-'); x = -x; }
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
const int N = 102;
ll a[N], b[N], n;
ll c[N], d[N];
bool check() {
for (int i = 1; i <= n; i++) if (c[i] != b[i]) return 0;
return 1;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
for (int a1 = 0; a1 <= 50; a1++) {
for (int i = 1; i <= n; i++) c[i] = a[i];
int ok = 1;
for (int k = 1; k <= a1; k++) {
for (int i = 1; i <= n; i++) d[i] = c[i] + c[i == 1 ? n : i - 1];
for (int i = 1; i <= n; i++) {
c[i] = d[i];
if (c[i] > b[i]) {
ok = 0;
break;
}
}
}
if (!ok) continue;
int a2 = 50;
while (a2--) {
if (check()) {
puts("Yes");
exit(0);
}
for (int i = 1; i <= n; i++) d[i] = c[i] + c[i == n ? 1 : i + 1];
for (int i = 1; i <= n; i++) {
c[i] = d[i];
if (c[i] > b[i]) {
break;
}
}
}
}
puts("No");
return 0;
}
[XJOI3529] 左右的更多相关文章
随机推荐
- java中checked异常和unchecked异常区别?
马克-to-win:checked和unchecked异常区别:结论就是:1)RuntimeException和他的子类都是unchecked异 常.其他的都是checked异常.马克-to-win: ...
- CCF201503-2数字排序
问题描述 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出. 输入格式 输入的第一行包含一个整数n,表示给定数字的个数. 第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所 ...
- python2.7安装pyinstaller
python2.7直接安装pyinstaller会报错,版本4与python2不兼容,所以我们安装时需指定兼容的pyinstaller版本号.安装命令如下: pip2 install pyinstal ...
- python版本共存与语法的注释
python的多种版本共存 首先还是先下载python解释器除最高版本的另外两个版本 个人推荐的是 3.6.8和2.7.14 首先我电脑是win7系统 在计算机属性右键点开高级设置点击环境变量 将下载 ...
- JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了
JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了 代码示例 转自 https://docs.oracle.com/javase/tutorial/jdbc/o ...
- C++STL 中的数值算法(iota、accumulate、adjacent_difference、inner_product、partial_sum)
以下算法均包含在头文件 numeric 中 ##1.iota 该函数可以把一个范围内的序列从给定的初始值开始累加 先看用法. 例: 假设我需要一个长度为10,从5开始递增的序列 vector<i ...
- 安卓记账本开发学习day4
在代码层面,展示出来的界面应该如下图 但是实际运行效果如下图 很明显,"其他"都没有显示出来,经过一点点排查,发现是IncomeFragment.java文件的代码存在错误 @Nu ...
- 在网站copy时自带的版权小尾巴以及“复制代码“,可以怎么实现
前言 每天网上的博客各个领域都会涌现新文章,有时候看到感兴趣的知识就想把某段文字 copy下来 摘录下来,等有时间后慢慢品味 在部分网站上,如果只是复制少量文字,并没有什么不同.但是当我们复制的文字多 ...
- 【课程汇总】OpenHarmony全场景Demo数字管家系列课(附链接)
小孩放学了,做作业的时间到,窗帘.护眼灯自动打开,关掉电视和扫地机,给小孩一个安静舒适的学习环境:碰到学习难题,可以随时请求你的远程指导:晚上回家休息了,选择舒适的氛围灯,伴随着睡眠音乐进入梦乡:出门 ...
- 2021.11.04 P1392 取数(多路归并)
2021.11.04 P1392 取数(多路归并) P1392 取数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 在一个n行m列的数阵中,你须在每一行取一个数(共n个数) ...