P9714「QFOI R1」摸摸

· · 个人记录

洛谷

题意

给定一个序列 a(初始全为 0)和一个序列 t,求是否可以通过以下两种操作使 a 变成 b(序列长度均为 n):

## 思路 考虑操作 1,容易证明只执行一次是没有影响的,因为因为执行 $k$ 次会让 $t$ 变成 $2^{k-1}(t+t')$,与先执行操作 1 一次再执行操作 2 $2^k$ 次没有区别。 于是就有这么一个想法:先加 $t$ $k_1$ 次,再加 $t+t'$ $k_2$ 次,枚举 $k_1,k_2(0\le k_1\le \left\lfloor\frac{\max b}{\min t}\right\rfloor,0\le k_2\le \left\lfloor\frac{\max b}{\min 2t}\right\rfloor)$,一定能符合要求或判断无解。 时间复杂度 $O(n\left\lfloor\frac{\max b}{\min t}\right\rfloor^2)$,赛时草过去了。 ```cpp #include<bits/stdc++.h> using namespace std; int n,b[2003],t[2003],tt[2003],T,mb,mt=3235345; void frdsgesgh(){ cin>>n; for(int i=1;i<=n;i++) cin>>t[i]; for(int i=1;i<=n;i++) cin>>b[i],tt[i]=t[i]+t[n-i+1]; for(int i=0;i<=2000;i++){ for(int j=0;j<=1000;j++){ bool f=1; for(int k=1;k<=n;k++) if(t[k]*i+tt[k]*j!=b[k]){ f=0; break; } if(f){ cout<<"YeS\n"; return; } } } cout<<"nO\n"; } signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>T; while(T--)frdsgesgh(); return 0; } ``` 即判断 $k_1t+k_2(t+t_1)=b$ 是否存在即可,应该有更快的做法。