当前位置:   article > 正文

D - Nezzar and Board(思维+裴蜀定理)

d - nezzar and board

https://codeforces.com/contest/1478/problem/D


题意:有n个数,可以进行一种操作得到2x−y, 原数不会消失,问能否得到k.

思路:

没思路硬模拟(或者看到这个多个数构成..感觉像裴蜀定理

2x−y 可以看做x+(x−y),即该数与两数之差的和。

用几组样例模拟一下,可以发现,无论进行多少次操作,始终都是ai​+∑{j,k}​(aj​−ak​),也就是在若干组差值加上一个值。

这样的话就是要n^2枚举差值了。但是还有个性质。a2-a1已知,a3-a2已知,是可以线性组合成a3-a1的,也就是说只要O(n),可以得到组成n^2所有差的原材料。

那么如果能被这(n-1)线性组合出来,那么其最终反应形态就是∑{j,k}​(aj​−ak​),只不过前面系数有0有其他值,各不相同。

于是就到了ai+∑{2~n}​(ai​−ai-1​)=K;

提前减去ai,转化∑{2~n}​(ai​−ai-1​)=K-ai;

前面的部分就是看gcd(左边一串)是否能被右边整除。(多个数的裴蜀定理嘛

然后最后可以On扫一下看有没有ai是满足答案的。

  1. #include<iostream>
  2. #include<vector>
  3. #include<queue>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<map>
  7. #include<set>
  8. #include<cstdio>
  9. #include<algorithm>
  10. #define debug(a) cout<<#a<<"="<<a<<endl;
  11. using namespace std;
  12. const int maxn=2e5+100;
  13. typedef long long LL;
  14. inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
  15. return x*f;}
  16. LL a[maxn];
  17. int main(void)
  18. {
  19. cin.tie(0);std::ios::sync_with_stdio(false);
  20. LL t;cin>>t;
  21. while(t--){
  22. LL n,k;cin>>n>>k;
  23. for(LL i=1;i<=n;i++) cin>>a[i];
  24. LL gcd=0;
  25. for(LL j=1;j<=n;j++){
  26. gcd=__gcd(gcd,a[j]-a[1]);
  27. }
  28. bool flag=1;
  29. for(LL i=1;i<=n;i++){
  30. if((k-a[i])%gcd==0){
  31. flag=0;
  32. cout<<"YES"<<"\n";
  33. break;
  34. }
  35. }
  36. if(1==flag) cout<<"NO"<<"\n";
  37. }
  38. return 0;
  39. }

 

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号