https://acm.ecnu.edu.cn/contest/292/problem/E/
E-因数串
题意:给定一个数n为几个素数的几次方,你要找到一个序列,使得不重复的输出数n的所有约数,同时这个序列的约束是a[i]要从a[i-1]乘上或除以某个素数,输出这个序列
思路:找规律,不想说啥 从第一个素数的个数先全部乘上,然后乘上另一个素数的一次方,然后出去这个之前素数的,具体看图把
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define rep(i, a, n) for(int i = a; i < n; i++)
#define per(i, a, n) for(int i = n-1; i >= a; i--)
#define IOS std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define INF 1ll<<60
#define fopen freopen("file.in","r",stdin);freopen("file.out","w",stdout);
#define fclose fclose(stdin);fclose(stdout);
const int maxn = 1e6+10;
inline int read(){
int 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();}
return x*f;
}
ll a[20], b[20];
ll c[maxn];
bool d[maxn];
int main(){
int n = read();
rep(i,0,n){
a[i]=read(),b[i]=read();
}
ll sum = 1;
int pos = 0;
printf("%lld\n", sum);
for(int j = 0; j < b[0]; j++){
sum *= a[0];
c[pos] = a[0];
d[pos++] = 1;
printf("%lld\n", sum);
}
for(int i = 1; i < n; i++){
int x;
x = pos-1;
for(int k = 0; k < b[i]; k++){
sum *= a[i];
d[pos] = 1;
c[pos++] = a[i];
printf("%lld\n", sum);
if(k%2==0){
for(int j = x; j >= 0; j--){
if(d[j]) sum/=c[j], d[pos]=0;
else sum*=c[j], d[pos]=1;
c[pos++] = c[j];printf("%lld\n", sum);
}
}else {
for(int j = 0; j <= x; j++){
if(d[j]) sum*=c[j], d[pos]=1;
else sum/=c[j], d[pos]=0;
c[pos++] = c[j];printf("%lld\n", sum);
}
}
}
}
return 0;
}