QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#149682 | #4920. 挑战分解质因数 | zhouhuanyi | 0 | 870ms | 4116kb | C++14 | 7.7kb | 2023-08-25 10:14:49 | 2023-08-25 10:14:52 |
Judging History
answer
#include<iostream>
#include<cstdio>
#include<cstdint>
#include<vector>
#include<string>
#include<iosfwd>
#include<algorithm>
#include<random>
#define N 1500
#define __builtin_ia32_adc(x,y,flag) __asm__("addb %3, %0\n\t" "adcq %2, %1\n\t" "setc %0":"+r"(flag),"+r"(x):"r"(y),"i"(-1):"cc")
using namespace std;
mt19937 RAND(random_device{}());
struct bigint{
typedef unsigned long long u64;
typedef unsigned __int128 u128;
typedef std::size_t st;
std::vector<u64> data;
bigint(){}
bigint(u64 x):data(x?std::vector<u64>{x}:std::vector<u64>{}){}
bigint(const std::string &s){
st pos=s.length();
int cnt=0;
u64 val=0;
while(pos){
pos--;
if(cnt==64){
data.push_back(val);
val=0;cnt=0;
}
val|=(u64)(s[pos]=='1')<<cnt;
++cnt;
}
if(cnt&&val)data.push_back(val);
}
explicit operator std::string()const{
if(data.empty())return "0";
bool t=0;
std::string ret;
for(int i=63;i>=0;i--){
t|=(data.back()>>i)&1;
if(t)ret+='0'|((data.back()>>i)&1);
}
st i=data.size()-1;
while(i){
i--;
for(int j=63;j>=0;j--)ret+='0'|((data[i]>>j)&1);
}
return ret;
}
explicit operator bool()const{return !data.empty();}
explicit operator u64()const{return data.empty()?0:data[0];}
st digit()const{
if(data.empty())return 0;
return (data.size()<<6)-__builtin_clzll(data.back());
}
bool operator==(const bigint &a)const{return a.data==data;}
bool operator!=(const bigint &a)const{return a.data!=data;}
bool operator<(const bigint &a)const{
if(data.size()!=a.data.size())return data.size()<a.data.size();
for(st i=data.size();i;){
i--;
if(data[i]!=a.data[i])return data[i]<a.data[i];
}
return 0;
}
bool operator>(const bigint &a)const{return a<(*this);}
bool operator<=(const bigint &a)const{return !(*this>a);}
bool operator>=(const bigint &a)const{return !(*this<a);}
bigint &operator<<=(st n){
if(data.empty())return *this;
int w=n&63;st z=n>>6;
st i=data.size();
bool flg=0;
if(w&&(data.back()>>(64-w)))data.push_back(0),flg=1;
data.resize(data.size()+z);
while(i){
i--;
if(flg)data[i+z+1]|=data[i]>>(64-w);
data[i+z]=data[i]<<w;
flg|=bool(w);
}
for(st i=0;i<z;i++)data[i]=0;
return *this;
}
bigint &operator>>=(st n){
int w=n&63;st z=n>>6,i=0;
for(;i+z<data.size();i++){
if(w&&i)data[i-1]|=data[i+z]<<(64-w);
data[i]=data[i+z]>>w;
}
while(data.size()>i)data.pop_back();
while(!data.empty()&&data.back()==0)data.pop_back();
return *this;
}
bigint operator<<(st n)const{return bigint(*this)<<=n;}
bigint operator>>(st n)const{return bigint(*this)>>=n;}
bigint &operator+=(const bigint &a){
data.resize(std::max(data.size(),a.data.size()));
bool carry=0;
for(st i=0;i<data.size();i++){
u64 rg=0;
if(i<a.data.size())rg=a.data[i];
__builtin_ia32_adc(data[i],rg,carry);
}
if(carry)data.push_back(1);
return *this;
}
bigint &operator-=(const bigint &a){
bool carry=1;
for(st i=0;i<data.size();i++){
u64 rg=-1;
if(i<a.data.size())rg=~a.data[i];
__builtin_ia32_adc(data[i],rg,carry);
}
while(!data.empty()&&data.back()==0)data.pop_back();
return *this;
}
bigint &operator++(){return *this+=bigint(1);}
bigint &operator--(){return *this-=bigint(1);}
bigint operator++(int){bigint tmp=*this;++*this;return tmp;}
bigint operator--(int){bigint tmp=*this;--*this;return tmp;}
bigint &operator*=(const bigint &a){
std::vector<u64> ret(data.size()+a.data.size());
for(st i=0;i<data.size();i++){
u64 carry=0;bool wcarry=0;
st k=i;
for(st j=0;j<a.data.size();j++,k++){
u128 r=data[i]*(u128)a.data[j]+carry;
u64 cur=r;
carry=r>>64;
__builtin_ia32_adc(ret[k],cur,wcarry);
}
while(carry||wcarry){
__builtin_ia32_adc(ret[k],carry,wcarry);
carry=0;k++;
}
}
while(!ret.empty()&&ret.back()==0)ret.pop_back();
data=ret;
return *this;
}
bigint &operator/=(const bigint &a){
if(a.digit()>digit()){
data.clear();
return *this;
}
st z=digit()-a.digit();
std::vector<u64> ret;
while(1){
bigint tmp=a<<z;
if(tmp<=*this){
*this-=tmp;
st v1=z>>6;
if(ret.size()<=v1)ret.resize(v1+1);
ret[v1]|=(u64)(1)<<(z&63);
}
if(!z)break;
z--;
}
data=ret;
return *this;
}
bigint &operator%=(const bigint &a){
if(a.digit()>digit())return *this;
st z=digit()-a.digit();
while(1){
bigint tmp=a<<z;
if(tmp<=*this)*this-=tmp;
if(!z)break;
z--;
}
return *this;
}
bigint operator+(const bigint &a)const{return bigint(*this)+=a;}
bigint operator-(const bigint &a)const{return bigint(*this)-=a;}
bigint operator*(const bigint &a)const{return bigint(*this)*=a;}
bigint operator/(const bigint &a)const{return bigint(*this)/=a;}
bigint operator%(const bigint &a)const{return bigint(*this)%=a;}
};
std::istream &operator>>(std::istream &st,bigint &a){
std::string s;st>>s;a=bigint(s);return st;
}
std::ostream &operator<<(std::ostream &st,const bigint &a){
return st<<(std::string)(a);
}
bigint n,phin,zero,one=bigint(1),two=bigint(2),pw2[N+1],pw[N+1],tong[N+1];
int length;
bigint gcd(bigint a,bigint b)
{
if (b==zero) return a;
return gcd(b,a%b);
}
bigint fast_pow(bigint a,bigint b,bigint p)
{
bigint res=one,mul=a;
while (b!=zero)
{
if (b%2!=zero) res=res*mul%p;
mul=mul*mul%p,b>>=1;
}
return res;
}
bigint get_pow(bigint a,int b)
{
bigint res=one,mul=a;
while (b)
{
if (b&1) res=res*mul;
mul=mul*mul,b>>=1;
}
return res;
}
bigint get_sqt(bigint a,int b)
{
int c=1500/b;
bigint res=zero;
for (int i=c;i>=0;--i)
if (get_pow(res+pw2[i],b)<=a)
res=res+pw2[i];
return res;
}
bigint get_rand(bigint x)
{
bigint res=zero;
for (int i=1;i<=1500;++i) res=res*2+(int)(RAND()&1);
return res%x;
}
void solve(bigint x)
{
if (x==one) return;
int cnt;
bigint a,b,g,d;
for (int i=1;i<=100;++i)
{
a=get_rand(x),g=gcd(a,x);
if (g==x) continue;
if (g!=1)
{
solve(g),solve(x/g);
return;
}
d=phin,cnt=0;
while (d%2==zero) d>>=1,cnt++;
pw[0]=fast_pow(a,d,x);
for (int j=1;j<=cnt;++j) pw[j]=pw[j-1]*pw[j-1]%x;
for (int j=cnt-1;j>=0;--j)
if (pw[j]!=one)
{
if (pw[j]+one==x) break;
else
{
g=gcd(pw[j]+1,x),solve(g),solve(x/g);
return;
}
}
}
for (int i=1500;i>=1;--i)
{
bigint res=get_sqt(x,i);
if (get_pow(res,i)==x)
{
for (int j=1;j<=i;++j) tong[++length]=res;
return;
}
}
return;
}
int main()
{
pw2[0]=one;
for (int i=1;i<=N;++i) pw2[i]=pw2[i-1]*two;
cin>>n>>phin,solve(n),printf("%d\n",length),sort(tong+1,tong+length+1);
for (int i=1;i<=length;++i) cout<<tong[i]<<endl;
return 0;
}
詳細信息
Subtask #1:
score: 0
Time Limit Exceeded
Test #1:
score: 5
Accepted
time: 2ms
memory: 4108kb
input:
1 1
output:
0
result:
ok "0"
Test #2:
score: 0
Accepted
time: 112ms
memory: 4060kb
input:
1000001010000010011000000000001 1000001010000000000000000000000
output:
2 100100000000001 1110100000000001
result:
ok 3 tokens
Test #3:
score: 0
Accepted
time: 110ms
memory: 3940kb
input:
100011100111101010100110101011 100011100111011001010101000000
output:
2 10011001001011 1110111000100001
result:
ok 3 tokens
Test #4:
score: 0
Accepted
time: 115ms
memory: 4116kb
input:
10001001101010010000101100001111 10001001101001111001001011011000
output:
2 1011000000011011 1100100000011101
result:
ok 3 tokens
Test #5:
score: 0
Accepted
time: 222ms
memory: 3948kb
input:
11010101110001001000101110100011 10001110011111110101111001100000
output:
4 11 11 100100101110011 101001011001001
result:
ok 5 tokens
Test #6:
score: 0
Accepted
time: 165ms
memory: 3936kb
input:
11110110100011100110011001 11110100100110011000000000
output:
3 100010101 101100001 1010010101
result:
ok 4 tokens
Test #7:
score: 0
Accepted
time: 381ms
memory: 4000kb
input:
11111101101000100101001011110000 1111110001100110011100011000000
output:
7 10 10 10 10 110111011 1010010011 1110001111
result:
ok 8 tokens
Test #8:
score: -5
Time Limit Exceeded
input:
10000000000000000000000000000000 1000000000000000000000000000000
output:
result:
Subtask #2:
score: 0
Skipped
Dependency #1:
0%
Subtask #3:
score: 0
Time Limit Exceeded
Test #31:
score: 10
Accepted
time: 799ms
memory: 3956kb
input:
100001100011000011110101000011010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010011101101001101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 10000...
output:
2 1111000011101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 10001110100110000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
result:
ok 3 tokens
Test #32:
score: 0
Accepted
time: 870ms
memory: 3956kb
input:
100011010001011001101110110101100000111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100010000101101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001...
output:
2 100100111000011101110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 111101001101001010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
result:
ok 3 tokens
Test #33:
score: -10
Time Limit Exceeded
input:
11111111110101100011000111001011110101010110011000101010110011100101111010010100000001011010101111111001000000000001001110101110000001011111111011000010101011101100111110100000110001110010101101101111110111101001101010010011011100110001101100111111001000100011100000000000110101111101000010011011001 ...
output:
result:
Subtask #4:
score: 0
Time Limit Exceeded
Test #46:
score: 0
Time Limit Exceeded
input:
11011110000000000010100100101011111000100001100010011001110111010100101110110011111101111100001110110100010000000001111000110000100110111011000111000111001010000001010111010001111111000111100110011010111001011011010001100010101001001111111101000110011110011101011100000001101110111011000101010101101 ...
output:
result:
Subtask #5:
score: 0
Skipped
Dependency #4:
0%
Subtask #6:
score: 0
Skipped
Dependency #5:
0%
Subtask #7:
score: 0
Skipped
Dependency #6:
0%