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 n 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 n 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 a, and the new prices as an array of non-negative integers b. Both arrays have the same length n.

In one operation, Vika constructs a new array c according to the following principle: ci=|aibi|. Then, array c renamed into array b, and array b renamed into array a at the same time, after which Vika repeats the operation with them.

For example, if a=[1,2,3,4,5,6,7]; b=[7,6,5,4,3,2,1], then c=[6,4,2,0,2,4,6]. Then, a=[7,6,5,4,3,2,1]; b=[6,4,2,0,2,4,6].

Vika decided to call a pair of arrays a, b dull if after some number of such operations all elements of array a 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 t (1t104) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer n (1n105) — the number of items whose prices have changed.

The second line contains n integers a1,a2,,an (0ai109) — the old prices of the items.

The third line contains n integers b1,b2,,bn (0bi109) — the new prices of the items.

It is guaranteed that the sum of n over all test cases does not exceed 105.

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 a is initially zero.

In the second test case, after the first operation a=[1,2,3],b=[0,0,0]. After the second operation a=[0,0,0],b=[1,2,3].

In the third test case, it can be shown that the array a will never become zero.

 

解题思路

  首先可以发现数组中对每一位的操作都是相互独立的,因此可以先求出每个ai第一次变成0时共操作了几次,假设为ci次,然后模拟一下可以发现再操作3次后ai又变成了0,因此看一下每个cimod3是否都相同,如果都一样说明某一时刻可以将数组a变成全0,否则无解(如果初始时ai=bi=0那么可以忽略,因此始终都是0)。

  大致思路就是上面说的那样,不过首先需要证明反复执行这个操作可以得到0。对于aibi至少有一个不为0的情况,如果有aibi,那么对(ai,bi)执行一次操作后就会变成(bi,aibi),数对总和从ai+bi减小到ai。如果ai<bi,在两次操作后就会变成(biai,ai),数对总和从ai+bi减少到bi。由于aibi始终是非负整数,因此其总和不可能一直减少,因此aibi一定会有一个变成0

  当经过ci次操作后,(ai,bi)变成(0,d)(实际上d=gcd(ai,bi)),再经过3次操作有(0,d)(d,d)(d,0)(0,d),即最终会形成一个周期为3的循环。因此要判断是否能将数组a变成全0,就要看每一个ci3是否都相同。因此求出ci就是关键。

  假设aibi(否则执行一次操作即可),令ai=kbi+r,那么有

(kbi+r,bi)(bi,(k1)bi+r)((k1)bi+r,(k2)bi+r)((k2)bi+r,bi)(bi,(k3)bi+r)((k3)bi+r,(k4)bi+r)((k4)bi+r,bi)(bi,(k5)bi+r)((k5)bi+r,(k6)bi+r)((k6)bi+r,bi)

  不断的操作下去最终会得到(bi,r)(r,bi)。令k为奇数,模拟一下可以发现经过3k2+1次操作后就会得到(bi,r)。令k为偶数,经过3k2次操作后就会得到(r,bi)。因此我们可以写个递归来求出(ai,bi)变成(0,d)所需要的次数ci,由于每一次都是对小于自身的数取模,因此相应的时间复杂度为O(logai)

  AC代码如下,时间复杂度为O(nlogA)

复制代码
 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

posted @   onlyblues  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-09-02 环形石子合并
Web Analytics
点击右上角即可分享
微信分享提示