主頁 >  其他 > 【ACM演算法競賽日常訓練】DAY16【奇♂妙拆分】【區區區間間間】【小AA的數列】數學 | 位運算 | 前綴和

【ACM演算法競賽日常訓練】DAY16【奇♂妙拆分】【區區區間間間】【小AA的數列】數學 | 位運算 | 前綴和

2023-04-21 07:51:04 其他

DAY16共3題:

  • 奇♂妙拆分(簡單數學)

  • 區區區間間間(單調堆疊)

  • 小AA的數列(位運算dp)

?? 作者:Eriktse
?? 簡介:19歲,211計算機在讀,現役ACM銀牌選手??力爭以通俗易懂的方式講解演算法!??歡迎關注我,一起交流C++/Python演算法,(優質好文持續更新中……)??
?? 閱讀原文獲得更好閱讀體驗:https://www.eriktse.com/algorithm/1119.html

奇♂妙拆分(簡單數學)

根據貪心的想法,若要使得因子盡可能多,那么因子應當盡可能小,大于根號n的因子至多一個,從小到大列舉[1, sqrt(n)]的所有整數,如果i能夠整除n就作為一個因子,

Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;

void solve()
{
    int n;cin >> n;
    set<int> st;
    for(int i = 1;i <= n / i; ++ i)
        if(n % i == 0)st.insert(i), n /= i;
    st.insert(n);
    
    cout << st.size() << '\n';
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _;cin >> _;
    while(_ --)solve();
    return 0;
}

區區區間間間(單調堆疊)

題意:給定一個陣列,求所有子區間的最大值與最小值的差的和,

如果暴力列舉肯定不行,單單是子區間個數就有n ^ 2個,所以我們應該考慮每一個元素對答案的貢獻,也就是說我們需要知道某個元素a[i]它會在多少個區間里作為最大值,在多少個區間里作為最小值

我們預處理出四個陣列,分別是lmax[], rmax[], lmin[], rmin[]表示點i作為最大值的左右最遠位置,和作為最小值的左右最遠位置(lmax[i] = j,表示在區間[j, i]中的最大值都是a[i],其他的三個陣列類似定義),

用單調堆疊可以處理出這四個陣列,一下以求lmax[]舉例,維護一個單調不增堆疊,堆疊記憶體放的是下標

初始時堆疊內僅有一個a[0] = inf

當我們遇到一個a[i]時,不斷地判斷堆疊頂元素,如果堆疊頂元素比a[i]小,說明這個堆疊頂應當彈出,

當更新完畢后,此時的堆疊頂的右邊相鄰位置就是a[i]往左的最遠的位置了,因為此時堆疊頂是a[i]往左的第一個大于等于a[i]的位置,那么這中間的元素都會小于a[i]

其他的三個陣列類似,注意,如果我們處理lmax用的是單調不增堆疊,那么處理rmax就應當用單調遞增堆疊,而不是單調不減堆疊,否則可能出現區間重復表示或沒有歸屬的問題(自己思考),

Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 9, inf =8e18;
int a[N], stk[N], top, lmax[N], rmax[N], lmin[N], rmin[N];

void solve()
{
    int n;cin >> n;
    for(int i = 1;i <= n; ++ i)cin >> a[i];
    a[0] = a[n + 1] = inf;
    
    top = 0;
    stk[++ top] = 0;
    for(int i = 1;i <= n; ++ i)
    {
        while(top && a[i] > a[stk[top]])top --;
        lmax[i] = stk[top] + 1;
        stk[++ top] = i;
    }
    
    top = 0;
    stk[++ top] = n + 1;
    for(int i = n;i >= 1; -- i)
    {
        while(top && a[i] >= a[stk[top]])top --;
        rmax[i] = stk[top] - 1;
        stk[++ top] = i;
    }
    
    
    a[0] = a[n + 1] = -inf;
    top = 0;
    stk[++ top] = 0;
    for(int i = 1;i <= n; ++ i)
    {
        while(top && a[i] < a[stk[top]])top --;
        lmin[i] = stk[top] + 1;
        stk[++ top] = i;
    }
    
    top = 0;
    stk[++ top] = n + 1;
    for(int i = n;i >= 1; -- i)
    {
        while(top && a[i] <= a[stk[top]])top --;
        rmin[i] = stk[top] - 1;
        stk[++ top] = i;
    }
    int ans = 0;
    for(int i = 1;i <= n; ++ i)
    {
        ans += a[i] * (rmax[i] - i + 1) * (i - lmax[i] + 1);
        ans -= a[i] * (rmin[i] - i + 1) * (i - lmin[i] + 1);
    }
    cout << ans << '\n';
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _;cin >> _;
    while(_ --)solve();
    return 0;
}

小AA的數列(位運算 | 前綴和)

這道題一看有點懵,感覺不是很好處理,但依然是套路題,

看到異或,我們應該想把每一個二進制位拆分開,實際上這里約32位二進制位可以先認為是相互獨立的,對于每一位都計算出貢獻,然后按照位權重加和即可,

異或題的套路基本都是拆分二進制,整體考慮起來比較復雜,拆分后會簡單很多,

先不管L, R

假如我們考慮陣列1 2 3 4 5的第0位:

獲取第0位后得到b陣列:1 0 1 0 1

因為我們要得到區間內1的個數,所以處理一個異或前綴和p[]是自然而然的,然后我們列舉每一位作為左端點,看看會得到一個怎樣的式子:

\[sum=\sum_{j=i + 1}^{j += 2, j \le n}p[j]\oplus p[i-1] \]

我們知道異或其實就是% 2的加法,也是% 2減法,所以我們將異或前綴和改為普通前綴和p[],以上的柿子可以轉化為:

\[sum=\sum_{j=i + 1}^{j += 2, j \le n}[(p[j] - p[i-1]) (mod 2)] \]

那么我們就可以對p再做一個前綴和p2,但是p2的步長應為2,

然后上面的柿子就等價于(其中l, rj的上下限,需要保證與i - 1奇偶性相同,j的個數為(r - l + 2) / 2):

\[sum=| p2[r] - p2[l - 1] - p[i - 1] * ((r - l + 2) / 2))| \]

因為這個p2存在p2[-1]的情況,所以我們做個小小的便宜,方便代碼的撰寫(其實你想要特判也行,只是不太方便,也容易出錯),

注意一下其他細節即可,

Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 109, p = 1e9 + 7, T = 100;
int a[N], b[N], p1[N], p2[N];


signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, l, r;cin >> n >> l >> r;
    for(int i = 1;i <= n; ++ i)cin >> a[i];
    
    int ans = 0;
    for(int w = 0;w <= 32; ++ w)
    {
        for(int i = 1;i <= n; ++ i)b[i] = a[i] >> w & 1;
        for(int i = 1;i <= n; ++ i)p1[T + i] = (b[i] + p1[T + i - 1]) % 2;
        for(int i = 1;i <= n; ++ i)p2[T + i] = p1[T + i] + p2[T + i - 2];
        
        int sum = 0;
        for(int i = 1;i <= n; ++ i)
        {
            int j1 = max(i + 1, l + i - 1), j2 = min(n, r + i - 1);
            if((j1 - i) % 2 == 0)j1 ++;
            if((j2 - i) % 2 == 0)j2 --;
            if(j2 < j1)continue;
            
            sum += abs(p2[T + j2] - p2[T + j1 - 2] - 
                       p1[T + i - 1] * ((j2 - j1) / 2 + 1));
        }
        ans = (ans + (1ll << w) * sum % p) % p;
    }
    cout << ans << '\n';
    return 0;
}

?? 本文由eriktse原創,創作不易,如果對您有幫助,歡迎小伙伴們點贊??、收藏?、留言??

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/550666.html

標籤:其他

上一篇:圖計算引擎分析--GridGraph

下一篇:返回列表

標籤雲
其他(157709) Python(38083) JavaScript(25376) Java(17984) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 【ACM演算法競賽日常訓練】DAY16【奇♂妙拆分】【區區區間間間】

    DAY16共3題: 奇♂妙拆分(簡單數學) 區區區間間間(單調堆疊) 小AA的數列(位運算dp) 🎈 作者:Eriktse 🎈 簡介:19歲,211計算機在讀,現役ACM銀牌選手🏆力爭以通俗易懂的方式講解演算法!??歡迎關注我,一起交流C++/Python演算法。(優質好文持續更新中……)🚀 🎈 ......

    uj5u.com 2023-04-21 07:51:04 more
  • 圖計算引擎分析--GridGraph

    GridGraph是一種單機核外圖處理系統,在大規模圖處理系統中充分利用磁盤讀寫,在有限記憶體中高效完成大規模圖計算。GridGraph充分利用磁盤大容量,解決單機記憶體有限時實作大規模圖計算問題。GridGraph采用Streaming-Apply方式減少計算中的IO 請求數量,通過檔案調入順序減少不... ......

    uj5u.com 2023-04-21 07:50:06 more
  • 護士排班

    護士排班問題是一種經典的優化問題,它的目標是為醫院的護士制定一個合理的排班計劃,以確保醫院的正常運轉。在本篇文章中,我們將介紹護士排班問題的背景、演算法思路以及實作方法。 一、背景 護士排班問題是一種 NP 難問題,它的目標是為醫院的護士制定一個合理的排班計劃,以確保醫院的正常運轉。在醫院中,護士的工 ......

    uj5u.com 2023-04-21 07:49:22 more
  • 時而實踐、時而學習

    讀毛選、林語堂的《蘇東坡傳》和德魯克的《卓有成效的管理》有感!提升自己的作業方法、管理方法和思想境界。 ......

    uj5u.com 2023-04-21 07:48:34 more
  • 詳解資料結構中堆疊的定義和操作

    摘要:本文為大家詳解資料結構中堆疊的定義和操作。 本文分享自華為云社區《資料結構:詳細講解堆疊的定義、堆疊的操作》,作者: 高彬滔 。 1.堆疊的定義 堆疊(stack):是只允許在一端進行插入或者洗掉操作的線性表(即后進先出,大概可以理解為吃飽了吐出來) 空堆疊:不含元素的空標配 堆疊頂:表尾端 堆疊底:表頭端 ......

    uj5u.com 2023-04-21 07:48:18 more
  • 數字先鋒 | 乘“云”之勢,天翼云助力長春市婦產醫院步入智慧醫療

    近年來,大資料、云計算、5G等新興技術逐步融入衛生健康服務各個領域,驅動傳統醫療衛生服務向數字健康發展階段邁進。各地醫療機構積極回應國家號召,推進醫院資訊化建設提檔升級,加快資訊系統云上部署,我國醫療行業正逐步邁向數字化轉型新階段。 長春市婦產醫院始建于1896年,是一所集預防、保健、醫療、康復、科 ......

    uj5u.com 2023-04-21 07:48:01 more
  • 時隔6年后,我又回到博客園了

    多年的程式員生涯,從青春年少到三十而立,迷迷糊糊又到了不惑之年,有很多話想找人說說,可默然回首,卻不知道說什么。 兢兢業業的作業,上有老,下有少,作業不敢有一絲失誤,當怕自己成那失業大軍的一員。 丟失了作業激情,也在俯首電腦間一年一年的磨滅了生活的激情。 想感嘆些什么,可又說不出什么。 這么些年,學 ......

    uj5u.com 2023-04-21 07:47:57 more
  • 做個清醒的程式員之拒絕作業

    難道我們可以自己決定做與不做什么作業嗎?作業內容不都是上級給安排好的嗎?如何處理那似乎總也無法清空的待辦事項串列?
    閱讀這篇文章,或許可以解決上述疑惑。 ......

    uj5u.com 2023-04-21 07:47:53 more
  • 我呼叫第三方介面遇到的13大坑

    在實際作業中,我們經常需要在專案中呼叫第三方API介面,獲取資料,或者上報資料,進行資料交換和通信。

    那么,呼叫第三方API介面會遇到哪些問題?如何解決這些問題呢?

    這篇文章就跟大家一起聊聊第三方API介面的話題,希望對你會有所幫助。 ......

    uj5u.com 2023-04-21 07:47:44 more
  • 年薪50W京東軟體測驗工程師的成長路 —— 我們都曾一樣迷茫

    ?和朋友談到軟體測驗行業的發展問題,其實軟體測驗現在已經不知不覺發生了非常大的變化,前幾年的軟體測驗行業還是一個風口,人才缺口巨大,隨著不斷地轉行人員以及畢業的大學生瘋狂地涌入軟體測驗行業,目前軟體測驗行業“缺口”已經基本飽和。 當然,我說的是最基礎的功能測驗的崗位需求已經很少了,而自動化、性能、安 ......

    uj5u.com 2023-04-21 07:47:03 more