牛客月赛40 H rank1哥的妙蛙思想

题目链接
大致思想就是
假设有x的话那么直接输出就好了 如果 没有 x
我们看他的倍数 y1 y2 y3… ym 如果 y2…ym都是 y1的倍数的话 那么肯定是不行的所以他这里做了一个处理 将每个数做后缀和 并且 开qpow(2,cnt) - 1 第二部分就是相减 如果 都是y1的倍数的话 那么 y1 要减去 y2…ym的数 又因为x是与他们相关的那么 x - y1 - y2…ym 又因为 y1 = y1 - y2…ym 且 x = y1 所以会变为 0 此时就是不存在这种情况 反之则存在 真的妙!

#pragma GCC target("popcnt")
#include <bits/stdc++.h>
#define maxn 1000010
#define ll long long
#define ull unsigned long long
#define ld long double
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define pii pair<int, int>
#define pil pair<int, ll>
#define pll pair<ll, ll>
#define IL inline
#define ss system
using namespace std;

int a[maxn], n, q;
const ll p = 1e9 + 7;
template <class T> void read(T &x) {
    
    
  char ch = x = 0;
  bool fl = false;
  while (!isdigit(ch))
    fl |= ch == '-', ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  x = fl ? -x : x;
}
ll pw(ll a, ll b) {
    
    
  ll ret = 1;
  while (b) {
    
    
    if (b & 1)
      ret = ret * a % p;
    a = a * a % p, b >>= 1;
  }
  return ret;
}
int main() {
    
    
  int T;
  read(T);
  while (T--) {
    
    
    read(n), read(q);
    for (int i = 1; i <= n; i++) {
    
    
      a[i] = 0;
    }
    for (int i = 1, x; i <= n; i++) {
    
    
      read(x), a[x]++;
    }
    for (int i = 1; i <= n; i++) {
    
    
      for (int j = i * 2; j <= n; j += i) {
    
    
        a[i] += a[j];
      }
    }
    for (int i = 1; i <= n; i++) {
    
    
      a[i] = (pw(2, a[i]) - 1 + p) % p;
    }
    for (int i = n; i; i--) {
    
    
      for (int j = i * 2; j <= n; j += i) {
    
    
        a[i] = ((ll)a[i] - a[j] + p) % p;
      }
    }

    for (int i = 1, x; i <= q; i++) {
    
    
      read(x), puts(a[x] ? "YES" : "NO");
    }
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qqqingyi/article/details/121172534
今日推荐