2024牛客(4)K題

登錄—專業IT筆試面試備考平臺_牛客網

using i64 = long long;
using ll = long long;
constexpr ll M = 1e9 + 7;
template<class Info>
struct SegmentTree {int n;std::vector<Info> info;SegmentTree() : n(0) {}SegmentTree(int n_, Info v_ = Info()) {init(n_, v_);}template<class T>SegmentTree(std::vector<T> init_) {init(init_);}void init(int n_, Info v_ = Info()) {init(std::vector<Info>(n_, v_));}template<class T>void init(std::vector<T> init_) {n = init_.size();info.assign(4 << (int)std::log2(n), Info());std::function<void(int, int, int)> build = [&](int p, int l, int r) {if (r - l == 1) {info[p] = init_[l];return;}int m = (l + r) / 2;build(2 * p, l, m);build(2 * p + 1, m, r);pull(p);};build(1, 0, n);}void pull(int p) {info[p] = info[2 * p] + info[2 * p + 1];}void modify(int p, int l, int r, int x, const Info& v) {if (r - l == 1) {info[p] = v;return;}int m = (l + r) / 2;if (x < m) {modify(2 * p, l, m, x, v);}else {modify(2 * p + 1, m, r, x, v);}pull(p);}void modify(int p, const Info& v) {modify(1, 0, n, p, v);}Info rangeQuery(int p, int l, int r, int x, int y) {if (l >= y || r <= x) {return Info();}if (l >= x && r <= y) {return info[p];}int m = (l + r) / 2;return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);}Info rangeQuery(int l, int r) {return rangeQuery(1, 0, n, l, r);}template<class F>int findFirst(int p, int l, int r, int x, int y, F pred) {if (l >= y || r <= x || !pred(info[p])) {return -1;}if (r - l == 1) {return l;}int m = (l + r) / 2;int res = findFirst(2 * p, l, m, x, y, pred);if (res == -1) {res = findFirst(2 * p + 1, m, r, x, y, pred);}return res;}template<class F>int findFirst(int l, int r, F pred) {return findFirst(1, 0, n, l, r, pred);}template<class F>int findLast(int p, int l, int r, int x, int y, F pred) {if (l >= y || r <= x || !pred(info[p])) {return -1;}if (r - l == 1) {return l;}int m = (l + r) / 2;int res = findLast(2 * p + 1, m, r, x, y, pred);if (res == -1) {res = findLast(2 * p, l, m, x, y, pred);}return res;}template<class F>int findLast(int l, int r, F pred) {return findLast(1, 0, n, l, r, pred);}
};struct Info {ll a;//表示黃色磚塊,當前ll b;ll c = 1;ll d;
};Info operator+(const Info& b, const Info& a) {//b.a + a.a * b.c//b.b + a.a * b.d + a.b //a.c * b.c//a.c * b.d + a.d return { (b.a + ((a.a%M) * (b.c%M))%M)%M, (b.b + ((a.a%M) * (b.d%M)) + a.b)%M, ((a.c%M) * (b.c%M))%M, (((a.c%M) * (b.d%M)%M) + a.d)%M };
}Info Y{ 0, 0, 1, 1 };
Info B{ 1, 0, 0, 1 };//箭頭指向下一個位置
Info R{ 0, 0, 2, 1 };//總數量乘以2在加上一個紅色磚塊int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int n, q;std::cin >> n >> q;std::string s;std::cin >> s;//最底層的n個區間,比如[0,1)表示第一個區間,代表第一塊磚SegmentTree<Info> seg(n);for (int i = 0; i < n; i++) {seg.modify(i, (s[i] == 'Y') ? Y : ((s[i] == 'B') ? B : R));/*for (int j = 0; j < n; j++) {Info t = seg.rangeQuery(j, j + 1);std::cout <<j<<":"<< t.a << ' ' << t.b << ' ' << t.c << ' ' << t.d << '\n';}*/}while (q--) {int o;std::cin >> o;if (o == 1) {int p;char c;std::cin >> p >> c;p--;seg.modify(p, (c == 'Y') ? Y : ((c == 'B') ? B : R));}else {int l, r;std::cin >> l >> r;l--;Info res = seg.rangeQuery(l, r);//b和d的和為總數ll ans = (res.b + res.d) % M;std::cout << ans << "\n";}}return 0;
}

第一點:std::vector<Info> info;存的是按區間字符操作后的效果,有點難理解,舉個例子,如果你查詢[0,1)這個區間相當于查詢按第一個字符進行游戲后的效果,如果第一個字符是Y,那么查詢的結果就是Info Y{ 0, 0, 1, 1 };至于Info為什么要這么定義我們來看看下面的內容.

其中最難理解的就是下面這一部分

struct Info {ll a;//最左邊的柱子的倍數ll b;//所有累計的方塊ll c = 1;//現有倍數ll d;//現有這一列的方塊
};Info operator+(const Info& b, const Info& a) {//b.a + a.a * b.c//b.b + a.a * b.d + a.b//a.c * b.c//a.c * b.d + a.d return { (b.a + ((a.a%M) * (b.c%M))%M)%M, (b.b + ((a.a%M) * (b.d%M)) + a.b)%M, ((a.c%M) * (b.c%M))%M, (((a.c%M) * (b.d%M)%M) + a.d)%M };
}Info Y{ 0, 0, 1, 1 };
Info B{ 1, 0, 0, 1 };//箭頭指向下一個位置
Info R{ 0, 0, 2, 1 };//總數量乘以2在加上一個紅色磚塊

首先a,b,c,d的意思我都標出來了,為什么要這么定義呢,我們這樣想,當中間有很多個操作B出現的時候,那么這個區間是不是有很多個柱子,這樣不清楚,讓我來畫個圖

如果產生了多個柱子是不是說明有操作B,第一個柱子不管是YRRY或是什么其它的操作它都不可能產生第二個柱子.假如我們要合并兩個區間,

每根柱子表示的無非就是YR的組合,可能是YYYY,RRRR又或者是YRRY等等,不存在B所以最后一根和第一根合并的序列一定是一根,那么效果是怎樣的呢,?顯然最后一根總方塊數我們可以設為k,那么合并后可以表示為((k+a1)*2+a2)*2+a3,原先第一根的方塊數為(a1*2+a2)*2+a3,兩者的差值不就是把k提到外面來嗎及(a1*2+a2)*2+a3+4*k(注意,我只是舉了一個只有兩個R情況下的例子,*2的數量要根據R的數量來定),那么+重載為什么這樣運算也很明顯了.

對于第一個算式b.a + a.a * b.c,再使用B之前,第一根的方塊數量和R的數量是不確定的,如果第一個區間有B,那么第一個區間的c變量是0,也就是說兩個區間合并后的第一根倍數就是b.a,如果第一個區間沒有B,說明第二個區間的第一根和第一個區間合并后會變成一根,即b.c不為0而b.a為0,合并后的第一根是a.a乘以b.c.

感覺解釋的不是很清楚(*/ω\*),換個解釋方法,Info Y{ 0, 0, 1, 1 };第一個1表示當前倍數為自己身的一倍,也就是不翻倍,第二個1表示添加到目前這根柱子里添加一個方塊,Info R{ 0, 0, 2, 1 };翻倍后添加,Info B{ 1, 0, 0, 1 };這涉及到好幾個運算,首先看最簡單的a.c*b.c表示第一根柱子已經固定了,根據之前講的最后一根和第一根合并的運算,我們要把當前倍數轉移到a變量里,及a.a * b.c,因為b是左邊的區間,所以按照這個運算,如果它在之前有過B字符,那么它也不為0,所以要加上b.a.

列舉了兩個,其它的是一樣的,就像是自動機一樣,涉及到有B和沒B的情況,比較難解釋,當涉及B的時候某些變量會自動變為0從而做出變換.

b.a(有B/沒B) + a.a(有B/沒B) * b.c(沒B/有B)
b.b(有B/沒B) + a.a(有B/沒B) * b.d?+ a.b(有B/沒B)? ? ? ? ?有Ba.a會把b.d添加到非當前柱子
a.c * b.c(沒B/有B)
a.c(沒B/有B) * b.d?+ a.d????????沒有B的時候a.c會把b.d添加到當前柱子?

大概就是這樣,盡力了,很難解釋.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696617.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696617.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696617.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue樣式綁定

1. 綁定 HTML class ①通過class名稱的bool值判斷樣式是否被啟用 <template><!--通過樣式名稱是否顯示控制樣式--><div :class"{ haveBorder: p.isBorder, haveBackground-color: p.isBackgroundcolor }">此處是樣式展示區域</div><br /…

Linux篇:開發工具yum/vim/gcc/g++/Makefile/gdb

一. yum&#xff1a;軟件包管理器 什么是軟件包&#xff1f; 在Linux 下安裝軟件 , 一個通常的辦法是下載到程序的源代碼 , 并進行編譯 , 得到可執行程序 . 但是這樣太麻煩了, 于是有些人把一些常用的軟件提前編譯好 , 做成軟件包 (可以理解成windows 上的安裝程序) 放在…

Linux C++ 字符編碼轉換 GBK與UTF8互轉

Linux 下使用 iconv 命令可以轉換文件的編碼 iconv -f GBK -t UTF-8 input_file -o output_fileC 代碼 使用 iconv 函數 iconv 函數簽名&#xff1a; size_t iconv(iconv_t cd,、 char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); 需要注意的是&…

Python基礎20 面向對象(3)多態、封裝、反射

文章目錄 一、多態1、什么是多態2、多態小實驗 二、封裝1、什么是封裝2、內部屬性的約定 三、反射1、什么是反射2、四個實現自省的函數&#xff08;1&#xff09;hasattr(object,name)&#xff08;2&#xff09;getattr(object,name,defaultNone)&#xff08;3&#xff09;seta…

神秘人暗訪:行政窗口為什么要開展神秘顧客調研

在競爭日益激烈的服務市場中&#xff0c;行政窗口作為公共服務的直接提供者&#xff0c;其服務質量的好壞直接關系到政府的形象和公眾對政府的信任度。為了更好地滿足市民的需求&#xff0c;提升服務質量&#xff0c;開展神秘顧客調查顯得尤為重要。神秘顧客調查的必要性包括以…

內網穿透的應用-如何本地部署Elasticsearch搜索分析引擎實現并發布公網遠程訪問

文章目錄 系統環境1. Windows 安裝Elasticsearch2. 本地訪問Elasticsearch3. Windows 安裝 Cpolar4. 創建Elasticsearch公網訪問地址5. 遠程訪問Elasticsearch6. 設置固定二級子域名 Elasticsearch是一個基于Lucene庫的分布式搜索和分析引擎&#xff0c;它提供了一個分布式、多…

探索Flask框架:打造優雅而強大的Web應用

在當今互聯網時代&#xff0c;Web應用的需求日益增長&#xff0c;而作為開發者&#xff0c;我們需要一個簡潔明快、靈活可擴展的框架來滿足這些需求。Flask框架作為一個Python微型框架&#xff0c;在其簡潔的設計理念和豐富的擴展生態系統之間找到了完美的平衡&#xff0c;為我…

洛谷--二分(Java實現)

洛谷 B3627 立方根 題目描述 給定正整數 n&#xff0c;求 √n?。答案向下取整。 輸入格式 僅一行&#xff0c;一個正整數 n。 輸出格式 僅一行&#xff0c;一個正整數&#xff0c;表示√n。向下取整輸出。 輸入輸出樣例 輸入 #1 27 輸出 #1 3 輸入 #2 100000 輸…

ORACLE之 decode函數

語法&#xff1a; DECODE(expression, search1, result1, search2, result2, ..., default_result) 其中&#xff0c;expression是要進行比較的表達式&#xff0c;search1, search2等是可能的值&#xff0c;result1, result2等是對應的結果。如果expression等于search1&#x…

Java類的成員、繼承、多態

當談論Java類的成員、繼承和多態時&#xff0c;我們談論的是面向對象編程的基本概念。讓我逐一介紹&#xff1a; 1. **成員**&#xff1a; - **字段&#xff08;Field&#xff09;**&#xff1a;也稱為屬性或變量&#xff0c;用于存儲對象的狀態信息。 - **方法&#xf…

防御保護第六次作業

需求: 8&#xff0c;分公司內部的客戶端可以通過域名訪問到內部的服務器 9&#xff0c;假設內網用戶需要通過外網的web服務器和pop3郵件服務器下載文件和郵件&#xff0c;內網的FTP服務器也需要接受外網用戶上傳的文件。針對該場景進行防病毒的防護。 10&#xff0c;我們需要針…

C++模板從入門到入土

1. 泛型編程 如果我們需要實現一個不同類型的交換函數&#xff0c;如果是學的C語言&#xff0c;你要交換哪些類型&#xff0c;不同的類型就需要重新寫一個來實現&#xff0c;所以這是很麻煩的&#xff0c;雖然可以cv一下&#xff0c;有了模板就可以減輕負擔。 下面寫一個適…

日常leetcode代碼思路總結(持續更新)

日常leetcode代碼思路總結&#xff08;持續更新&#xff09; 難易leecode題號題目描述思路簡單121. 買賣股票的最佳時機只準一次買賣0表示持有&#xff0c;1表示不持有&#xff1b;dp[0][i] max(dp[0][i-1], -prices[i])&#xff1b;dp[1][i] max(dp[1][i-1], dp[0][i] pric…

Openwrt刪除內核patch

環境說明 ubuntu-18.04 openwrt-21.02 安裝quilt sudo apt install quilt quilt指令說明 Usage: quilt [--trace[=verbose]] [--quiltrc=XX] command [-h] ...quilt --version Commands are:add fold mail refresh snapshotannotate fork new rem…

基于springboot+vue的中小企業設備管理系統(前后端分離)

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

H 橋逆變方式介紹(雙極性)

單極性控制和雙極性控制是說IGBT四個管子的控制 前面所說的單極性控制是其中一個管子開通、關閉另外一個管子持續開通 而雙極性是四個管子中的兩個管子同時導通&#xff0c;同時關斷。彼此交替變化 所以當方波出現低電平時&#xff0c;是一對管子同時導通&#xff0c;出現高電…

2.21 Qt day2 菜單欄/工具欄/狀態欄/浮動窗口、UI界面、信號與槽

思維導圖 使用手動連接&#xff0c;將登錄框中的取消按鈕使用qt4版本的連接到自定義的槽函數中&#xff0c;在自定義的槽函數中調用關閉函數 將登錄按鈕使用qt5版本的連接到自定義的槽函數中&#xff0c;在槽函數中判斷ui界面上輸入的賬號是否為"admin"&#xff0c;…

成像光譜遙感技術中的AI革命:ChatGPT應用指南

“成像光譜遙感技術中的人工智能革命&#xff1a;ChatGPT應用指南”&#xff0c;這是一門旨在改變您使用人工智能處理遙感數據的方式。將最新的人工智能技術與實際的遙感應用相結合&#xff0c;提供不僅是理論上的&#xff0c;而且是適用和可靠的工具和方法。無論你是經驗豐富的…

golang實現延遲隊列(delay queue)

golang實現延遲隊列 1 延遲隊列&#xff1a;郵件提醒、訂單自動取消 延遲隊列&#xff1a;處理需要在未來某個特定時間執行的任務。這些任務被添加到隊列中&#xff0c;并且指定了一個執行時間&#xff0c;只有達到指定的時間點時才能從隊列中取出并執行。 應用場景&#xff1…

智慧驛站_智慧文旅驛站_輕松的驛站智慧公廁_5G智慧公廁驛站_5G模塊化智慧公廁

多功能城市智慧驛站是在智慧城市建設背景下&#xff0c;所涌現的一種創新型社會配套設施。其中&#xff0c;智慧公廁作為城市智慧驛站的重要功能基礎&#xff0c;具備社會配套不可缺少的特點&#xff0c;所以在應用場景上&#xff0c;擁有廣泛的需求和要求。那么&#xff0c;城…