import java.math.*; import java.io.*; //==========================================================C // OS(Quadratic Sieve) Main Program C // 2次ふるい法javaプログラム ふるい改良3(改良3+(4)追加) C // + 行列改良2(行列をbitで表示) C //  (1) ふるいは倍精度浮動小数点を使用し、本来のふるい処理 C // (2) 素数基底に-1を追加 C // (3) 素数基底のh倍の素数も2個存在すればふるいで採用 C // (4) f(x)=x^2-Nの基底での分解方法の改良(ふるいを応用) C //----------------------------------------------------------C // 1. M = (int)sqrt(N) C // using Bsqrt C // 2. Seting the Factor Base C // Prime Table: PTB[NP] C // Factor Base: FTB[NB] C // Used Base: UTB[NBU] C // 3. Sieving by QS C // Sieved Matrix: MQS[ND][NBU] C //----------------------------------------------------------C // Written by Yasunori Ushiro , 2008/09/30 C // ( Tokyo Kougei University ) C // 後 保範: 東京工芸大学 C //==========================================================C public class TQS5{ public static void main (String[] args) throws Exception { String s; int k, j, IO; int NV[] = new int[5]; BigInteger N, M, P, Q; int NB, NBS, ND, NS, NP, NPP, LP, h; long t1,t2,t3,t4; BigInteger One = new BigInteger("1"); double T1,T2,T3; // I/O File set FileInputStream fi = new FileInputStream("data.txt"); InputStreamReader in = new InputStreamReader(fi); BufferedReader bin = new BufferedReader(in); FileOutputStream fo = new FileOutputStream("Sieve.txt"); PrintWriter out = new PrintWriter(fo,true); s = bin.readLine(); N = new BigInteger(s); s = bin.readLine(); NPP = Integer.parseInt(s); s = bin.readLine(); LP = Integer.parseInt(s); s = bin.readLine(); h = Integer.parseInt(s); NP = NPP*h; // IO=0 --> 分解結果だけ出力、IO=1 --> 途中情報出力 // IO=2 --> 行列及び分解行列出力 s = bin.readLine(); IO = Integer.parseInt(s); QS5 q = new QS5(); // 入力データの大きさチェック if(NP > q.szNP) NP = q.szNP; if(LP > q.szwk) LP = q.szwk; out.println("2次ふるい法による因数分解"); out.println(); out.println(" N=P×Qと分解する, M=sqrt(N)"); // QS t1 = System.currentTimeMillis(); M = q.QS(N, NP, LP, h, NV); NB = NV[0]; ND = NV[1]; NS = NV[2]; NBS = NV[3]; out.println(" N="+N.toString()); out.println(" M="+M.toString()); out.println(); int NNN = ND - NV[4]; out.println(" データ数="+ND+", (1次)="+NV[4]+", (2次)="+NNN); int NNS = q.NBU - NV[3]; out.println(" 基底の数="+q.NBU+", (1次)="+NV[3]+", (2次)="+NNS); out.println(" ふるいテーブル数="+NS+", 総ふるい数="+q.NOS); out.println(" 2次候補データ="+q.NH+", 2次非取得データ="+q.NNZ); // out.println(" 2次候補データ="+q.NH); out.println(" 1次素数NO="+NPP+", 2次比="+h+", 区間="+LP); int NBB = NB - NBS; out.println(" 1次基底NO="+NBS+", 2次基底NO="+NBB); out.println(" 1次最大素数="+q.FTB[NBS-1]+", 2次素数="+q.FTB[NB-1]); if(IO >= 1) { out.println("分解基底"); for (k=0; k= 3) { out.println("最終区間のふるいデータ"); out.println("S, /f(S), (M+S)^2-N, f(S)"); for (k=0; k= 2) { out.println("ふるい結果"); for (k=0; k=1 ) out.println("従属数="+ID); t3 = System.currentTimeMillis(); // Output AM,VC,VP if(IO >= 2) { out.println("A+E"); for (k=0; k