#include<bits/stdc++.h>
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=5e5+30;
vector<ll>dp,pd;
unordered_map<ll,int>mp;//作用同MAP,但是底层是用HASH
int main(){
int n;
ll x;
cin>>n>>x;//读入数组长及第一个数
dp.push_back(x);//压入第一个数,注意是DP
++mp[x];//键值为X对应的值变为1,首先该数自身就可以表示一个GCD值
cout<<x<<endl;
for(int i=2;i<=n;++i){
cin>>x;
pd.push_back(x);//读入压入当前最新的数到PD,PD每次都更新,现在仅一个数
++mp[x];//对应键值继续加1
cout<<x<<endl;
ll tmp=x;//把当前输入的最新值为为临时值
for(int j=0;j<dp.size();++j){//把当前的DP表扫一次,注意当前最新读的数没进DP
x=__gcd(x,dp[j]);//把X赋为其与DP表中第J个数的GCD,此函数可以直接求GCD
if(x!=tmp){//如果X变小了,就把X赋给TMP,MP该值+1,PD押入X
tmp=x;
++mp[x];
cout<<x<<endl;
pd.push_back(x);
}
}
swap(dp,pd);//把PD赋给DP,然后自清空
pd.clear();
}
printf("%d\n",mp.size());//最后MP有多少个不同的键值,亦即不同GCD,就是答案
return 0;
}
模拟过程:
DP读入第一个数,记入MP
PD读入第二个数,记入MP,然后与DP的数比较,如果有变小,又记入MP(表明出现了GCD,当然不排除之前出现过),就把变小的值压入PD
PD与DP交换,然后PD清空,每次都只用于最新值输入的比较,而DP是记录了逆序离当前输入的有效GCD比较值
注:代码中的cout<<x<<endl;可以明显地看出押入MP的顺序
Sample Input 1 4 9 6 2 4 6 Sample Output 6
6 4 9 6 2 4 6
----insert---1 4
dp 4
pd
----insert---2 9
1
now is 2
dp 4
pd 9 1
----insert---3 6
3
1
now is 3
dp 9 1
pd 6 3 1
----insert---4 2
1
now is 4
dp 6 3 1
pd 2 1
----insert---5 4
2
1
now is 5
dp 2 1
pd 4 2 1
----insert---6 6
2
1
now is 6
dp 4 2 1
pd 6 2 1
6
#include<bits/stdc++.h>
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=5e5+30;
vector<ll>dp,pd;
map<ll,int> mp;//作用同MAP,但是底层是用HASH
int main(){
int n;
ll x;
cin>>n>>x;//读入数组长及第一个数
dp.push_back(x);//压入第一个数,注意是DP
++mp[x];//键值为X对应的值变为1,首先该数自身就可以表示一个GCD值
cout<<"----insert---"<<1<<' '<<x<<endl;
cout<<"dp ";for(int kk=0;kk<dp.size();kk++)cout<<dp[kk]<<' ';cout<<endl;
cout<<"pd ";for(int kk=0;kk<pd.size();kk++)cout<<pd[kk]<<' ';cout<<endl;
for(int i=2;i<=n;++i){
cin>>x;
pd.push_back(x);//读入压入当前最新的数到PD,PD每次都更新,现在仅一个数
++mp[x];//对应键值继续加1
cout<<"----insert---"<<i<<' '<<x<<endl;
ll tmp=x;//把当前输入的最新值为为临时值
for(int j=0;j<dp.size();++j){//把当前的DP表扫一次,注意当前最新读的数没进DP
x=__gcd(x,dp[j]);//把X赋为其与DP表中第J个数的GCD,此函数可以直接求GCD
if(x!=tmp){//如果X变小了,就把X赋给TMP,MP该值+1,PD押入X
tmp=x;
++mp[x];
cout<<x<<endl;
pd.push_back(x);
}
}
cout<<"now is "<<i<<endl;
cout<<"dp ";for(int kk=0;kk<dp.size();kk++)cout<<dp[kk]<<' ';cout<<endl;
cout<<"pd ";for(int kk=0;kk<pd.size();kk++)cout<<pd[kk]<<' ';cout<<endl;
swap(dp,pd);//把PD赋给DP,然后自清空
pd.clear();
}
printf("%d\n",mp.size());//最后MP有多少个不同的键值,亦即不同GCD,就是答案
return 0;
}