L - Non-Prime Factors (質數篩選+因數分解)

来源:https://www.cnblogs.com/Remilia-Scarlet/archive/2019/04/19/10733424.html
-Advertisement-
Play Games

In many programming competitions, we are asked to find (or count the number of) Prime Factors of an integer i. This is boring. This time, let’s count ...


In many programming competitions, we are asked to find (or count the number of) Prime Factors of an integer i. This is boring. This time, let’s count the number of Non-Prime Factors of an integer i, denoted as NPF(i).

For example, integer 100 has the following nine factors: {1,2,4,5,10,20,25,50,100}. The two which are underlined are prime factors of 100 and the rest are non-prime factors. Therefore, NPF(100) = 7.

Input

The first line contains an integer Q (1Q310^6) denoting the number of queries. Each of the next Q lines contains one integer (2i210^6).

Output

For each query i, print the value of NPF(i).

Warning

The I/O files are large. Please use fast I/O methods.

Sample Input 1Sample Output 1
4
100
13
12
2018
7
1
4
2

題目大意:第一行給一個Q,代表Q次查詢,接下來Q行,每行一個整數i,求NPF(i)

    拿樣例100來說,100的因數有(1,2,4,5,10,20,25,50,100)共9個,其中2和5是質數(一個大於1的自然數,除了1和它本身外,不能被其他自然數整除),應去掉,剩下7個。

    所以NPF(100)= 7

    拿樣例13來說,13的因數有(1,13)共2個,其中13是質數,去掉後,剩下1個。

    所以NPF(13)= 1

 

解題思路:1.先預處理出1-2*10^6的質數。可以用eratosthenes篩法,時間複雜度O(NloglogN)(某位網友說的)

     2.預處理答案,先看代碼:

for(int i = 1; i <= 2000000; ++i){
        int rt = 2000000/i;
        for(int j = i; j <= rt; ++j){
            if(vis[i]){//非質數 
                ++ans[i*j];
            }
            if(vis[j] && i!=j){
                ++ans[i*j];
            }
        }
    }

  第一個for迴圈,表示1到2*10^6的數。

  第二個for迴圈,對於當前的數i,對 i 到 i*rt 進行處理

  舉個慄子,對於100來說,ans【100】初始化是0

  第一個迴圈到1時

    在第二個迴圈中:判斷1是非質數第一個if中必然會有1*100=100,即ans【100】++;(100<rt,必然出現)

            第二個if中會出現j=100,100是非質數,又100*1=100,即ans【100】++;

  tip:當i=100時,j 從100開始累加而且 j 不會回溯,所以100=1*100這一種分解方法會在i=1的時候處理出來

    即ans【100】+=2;

  第一個迴圈到2時

    在第二個迴圈中:第一個if  判斷2是質數,跳過(相當於把2這個因數剔除了,即沒有加入答案中)

            第二個if  j=50時,50是非質數,又50*2=100,所以ans【100】++;

  第一個迴圈到4時

    在第二個迴圈中:第一個if  判斷4是非質數,4*25=100,ans【100】++;

            第二個if  j=25時,25是非質數,25*4=100,所以ans【100】++;

  第一個迴圈到5時

    在第二個迴圈中:第一個if  判斷5是質數,跳過,

            第二個if  j=20時,20是非質數,20*5=100,所以ans【100】++;

  第一個迴圈到10時

    在第二個迴圈中:第一個if  判斷10是非質數,10*10=100,ans【100】++;

            第二個if  j=10時,10是非質數,但是i=j,跳過(相同因數處理一次即可,在第一個if處理了)

  第一個迴圈到20時:20*5=100,但是5不會出現,因為j是從20開始不斷累加,ans【100】已經處理結束了,從上面分析可以看出ans【100】=7;

  類似的,每個答案都可以在這2個迴圈中處理出來。

  時間上:當i=1來說,rt=2*10^6,j會從1加到2*10^6

      當i=2,rt=10^6,   j會從2加到10^6;

      ......  

      當i=10,rt=2*10^5,j會從10加到2*10^5(此時數量級已經降了一級)

      ...

      當i=100,rt=2*10^4,j會從1加到2*10^4

      ....

      當i=1000,rt=2*10^3,j會從1000加到2000(共1000次)

      .....

      當i=sqrt(2*10^6) rt=i,第二層迴圈直接跳過,後面一樣,都是1次

把它們加起來,大概也就10^7左右(目測估計法算的)

預處理10^6左右,Q個問題3*10^6,加起來數量級也在10^7

某位大佬說10^7的數量級一般都能在1s跑完,要看測評機

一開始我是對每次枚舉每個數的因數(1-sqrt(n)),然後想辦法優化,結果都是超時....((╯‵□′)╯︵┻━┻)

啟示:優化的時候想想辦法讓回溯的次數少一點。

AC代碼:

#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
bool vis[2000005];
int ans[2000005];
void init()
{
    //開始篩,vis=1表示該數不是質數
    vis[1]=1;
    int m=sqrt(2000002+0.5);
    for(int i=2;i<=m;++i) 
    if(!vis[i]) for(int j=i*i;j<=2000002;j+=i) vis[j]=1;
     //篩選結束    
    for(int i = 1; i <= 2000000; ++i){
        int rt = 2000000/i;
        for(int j = i; j <= rt; ++j){
            if(vis[i]){//非質數 
                ++ans[i*j];
            }
            if(vis[j] && i!=j){
                ++ans[i*j];
            }
        }
    }
}
int main()
{
    init();
    int Q;
    scanf("%d",&Q);
    while(Q--)
    {
        int n;
        scanf("%d",&n);
        printf("%d\n",ans[n]);
    }
    return 0;
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 現在很多朋友都想進軍IT行業,但是卻不知道學習前端或者後端好,對於這個問題小猿圈視頻網站的講師今天就為你講一下前端和後端的區別有哪些,你可以針對的選一下,這樣為你的以後IT之路有一個更好的選擇。 ...
  • 背景 不同於《編寫代碼的「八榮八恥」》,《穩定性「三十六計」》是應用於設計階段的非手腳架方式的標準化。 在實際工作中,通常會提倡給新人機會,讓他們自己去設計系統。這時候如果沒有一種標準化的check機制,會影響整個系統的質量。《穩定性「三十六計」》在實際項目中,我們作為設計階段的checklist來 ...
  • 上個月試了一波水,記錄了面試官的問題,問題答案自己對應的百度,希望對大家有幫助 1.設計模式的六大原則2.如果讓你設計一個RPC,你怎麼設計3.高併發的單列模式4.連接池的submit和execute的聯繫和區別5.怎麼避免重覆消費6.講一講noi和bio7.既然講到了selector 那你講講se ...
  • php與mysql資料庫,PHP支持很多資料庫,與mysql為牛逼組合,mysql資料庫的基礎知識的掌握是由必要的,要瞭解如何操作mysql資料庫,數據表的方法。 什麼是資料庫,資料庫能做什麼,資料庫有什麼好處,資料庫的基礎必備技術,備份和恢復的方法。 mysql的好處,功能強大,支持跨平臺,運行速 ...
  • 進行文件上傳前需要添加相應的依賴 在xml文件中進行相應的文件上傳解析器的配置 註意:這裡有個坑,因為沒註意,再排查錯誤的時候花了一點時間。就是給bean的id一定要是。 否者就會報如下的錯誤: ...
  • 1,今日內容: 二,深淺拷貝 三,元組類型 四,字典類型 五,字典的定義 六,字典的操作 七,集合類型 ...
  • 關於SpringMVC頁面向Controller傳參的問題,看了網上不少帖子,大多總結為以下幾類: 1、直接把頁面表單中相關元素的name屬性對應的值作為Controller方法中的形參。 這個應該是最直接的,我看的那本書從百度的編輯器中取內容content時就直接用的這個方法: 2、通過@Requ ...
  • 一、什麼是進程 進程(Process)是電腦中的程式關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的電腦結構中,進程是程式的基本執行實體;在當代面向線程設計的電腦結構中,進程是線程的容器。程式是指令、數據及其組織形式的描述,進程是程 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...