結果

問題 No.917 Make One With GCD
ユーザー furafura
提出日時 2020-05-15 12:47:22
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 20 ms / 2,000 ms
コード長 844 bytes
コンパイル時間 2,513 ms
コンパイル使用メモリ 202,640 KB
最終ジャッジ日時 2025-01-10 11:06:09
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 32
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:20:21: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   20 |         int n; scanf("%d",&n);
      |                ~~~~~^~~~~~~~~
main.cpp:22:23: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   22 |         rep(i,n) scanf("%d",&a[i]);
      |                  ~~~~~^~~~~~~~~~~~

ソースコード

diff #

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;
using lint=long long;

vector<long long> divisors(long long a){
	vector<long long> res;
	for(long long i=1;i*i<=a;i++) if(a%i==0) {
		res.emplace_back(i);
		if(i*i<a) res.emplace_back(a/i);
	}
	sort(res.begin(),res.end());
	return res;
}


int main(){
	int n; scanf("%d",&n);
	vector<int> a(n);
	rep(i,n) scanf("%d",&a[i]);

	vector<lint> D;
	rep(i,n) for(lint d:divisors(a[i])) D.emplace_back(d);
	sort(D.begin(),D.end());
	D.erase(unique(D.begin(),D.end()),D.end());

	int m=D.size();
	vector<lint> dp(m); // dp[i] = (gcd が D[i] になる部分列の総数)
	for(int i=m-1;i>=0;i--){
		int cnt=0;
		rep(j,n) if(a[j]%D[i]==0) cnt++;
		dp[i]=(1LL<<cnt)-1;
		for(int k=i+1;k<m;k++) if(D[k]%D[i]==0) dp[i]-=dp[k];
	}
	printf("%lld\n",dp[0]);

	return 0;
}
0