C. Vika and Price Tags
C. Vika and Price Tags
Vika came to her favorite cosmetics store "Golden Pear". She noticed that the prices of items have changed since her last visit.
She decided to analyze how much the prices have changed and calculated the difference between the old and new prices for each of the items.
Vika enjoyed calculating the price differences and decided to continue this process.
Let the old prices be represented as an array of non-negative integers , and the new prices as an array of non-negative integers . Both arrays have the same length .
In one operation, Vika constructs a new array according to the following principle: . Then, array renamed into array , and array renamed into array at the same time, after which Vika repeats the operation with them.
For example, if ; , then . Then, ; .
Vika decided to call a pair of arrays , dull if after some number of such operations all elements of array become zeros.
Output "YES" if the original pair of arrays is dull, and "NO" otherwise.
Input
Each test consists of multiple test cases. The first line contains a single integer () — the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer () — the number of items whose prices have changed.
The second line contains integers () — the old prices of the items.
The third line contains integers () — the new prices of the items.
It is guaranteed that the sum of over all test cases does not exceed .
Output
For each test case, output "YES" if the pair of price arrays is dull, and "NO" otherwise.
You can output each letter in any case (lowercase or uppercase). For example, the strings "yEs", "yes", "Yes", and "YES" will be accepted as a positive answer.
Example
input
9 4 0 0 0 0 1 2 3 4 3 1 2 3 1 2 3 2 1 2 2 1 6 100 23 53 11 56 32 1245 31 12 6 6 6 7 1 2 3 4 5 6 7 7 6 5 4 3 2 1 3 4 0 2 4 0 2 3 2 5 2 1 3 4 2 6 1 4 2 2 0 0 0 3
output
YES
YES
NO
NO
YES
YES
NO
YES
YES
Note
In the first test case, the array is initially zero.
In the second test case, after the first operation . After the second operation .
In the third test case, it can be shown that the array will never become zero.
解题思路
首先可以发现数组中对每一位的操作都是相互独立的,因此可以先求出每个第一次变成时共操作了几次,假设为次,然后模拟一下可以发现再操作次后又变成了,因此看一下每个是否都相同,如果都一样说明某一时刻可以将数组变成全,否则无解(如果初始时那么可以忽略,因此始终都是)。
大致思路就是上面说的那样,不过首先需要证明反复执行这个操作可以得到。对于和至少有一个不为的情况,如果有,那么对执行一次操作后就会变成,数对总和从减小到。如果,在两次操作后就会变成,数对总和从减少到。由于和始终是非负整数,因此其总和不可能一直减少,因此和一定会有一个变成。
当经过次操作后,变成(实际上),再经过次操作有,即最终会形成一个周期为的循环。因此要判断是否能将数组变成全,就要看每一个模是否都相同。因此求出就是关键。
假设(否则执行一次操作即可),令,那么有
不断的操作下去最终会得到或。令为奇数,模拟一下可以发现经过次操作后就会得到。令为偶数,经过次操作后就会得到。因此我们可以写个递归来求出变成所需要的次数,由于每一次都是对小于自身的数取模,因此相应的时间复杂度为。
AC代码如下,时间复杂度为:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 1e5 + 10; 5 6 int a[N], b[N]; 7 8 int dfs(int a, int b) { 9 if (!a) return 0; // a=0不需要操作 10 if (!b) return 1; // b=0再操作一次即可 11 if (a < b) return 1 + dfs(b, b - a); // a>b,操作一次使得a<=b 12 int k = a / b; 13 if (k & 1) return k / 2 * 3 + 1 + dfs(b, a % b); // k是奇数,最后得到(b, r) 14 return k / 2 * 3 + dfs(a % b, b); // k是偶数,最后得到(r, b) 15 } 16 17 void solve() { 18 int n; 19 scanf("%d", &n); 20 for (int i = 0; i < n; i++) { 21 scanf("%d", a + i); 22 } 23 for (int i = 0; i < n; i++) { 24 scanf("%d", b + i); 25 } 26 set<int> st; 27 for (int i = 0; i < n; i++) { 28 if (!a[i] && !b[i]) continue; // 跳过a[i]和b[i]均为0的情况 29 st.insert(dfs(a[i], b[i]) % 3); 30 if (st.size() > 1) { // 存在至少两个不同的ci%3 31 printf("NO\n"); 32 return; 33 } 34 } 35 printf("YES\n"); 36 } 37 38 int main() { 39 int t; 40 scanf("%d", &t); 41 while (t--) { 42 solve(); 43 } 44 45 return 0; 46 }
参考资料
Codeforces Round #885 (Div.2) Editorial:https://codeforces.com/blog/entry/118333
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17673661.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-09-02 环形石子合并