P7453 [THUSC 2017] 大魔法師 Solution

Description

給定序列 a = ( a 1 , a 2 , ? , a n ) a=(a_1,a_2,\cdots,a_n) a=(a1?,a2?,?,an?) b = ( b 1 , b 2 , ? , b n ) b=(b_1,b_2,\cdots,b_n) b=(b1?,b2?,?,bn?) c = ( c 1 , c 2 , ? , c n ) c=(c_1,c_2,\cdots,c_n) c=(c1?,c2?,?,cn?),有 m m m 個操作分七種:

  • e x c a ? ( l , r ) \operatorname{exc_a}(l,r) exca?(l,r):對每個 i ∈ [ l , r ] i\in[l,r] i[l,r] 執行 a i ← a i + b i a_i\gets a_i+b_i ai?ai?+bi?.
  • e x c b ? ( l , r ) \operatorname{exc_b}(l,r) excb?(l,r):對每個 i ∈ [ l , r ] i\in[l,r] i[l,r] 執行 b i ← b i + c i b_i\gets b_i+c_i bi?bi?+ci?.
  • e x c c ? ( l , r ) \operatorname{exc_c}(l,r) excc?(l,r):對每個 i ∈ [ l , r ] i\in[l,r] i[l,r] 執行 c i ← c i + a i c_i\gets c_i+a_i ci?ci?+ai?.
  • add ? ( l , r , v ) \operatorname{add}(l,r,v) add(l,r,v):對每個 i ∈ [ l , r ] i\in[l,r] i[l,r] 執行 a i ← a i + v a_i\gets a_i+v ai?ai?+v.
  • mul ? ( l , r , v ) \operatorname{mul}(l,r,v) mul(l,r,v):對每個 i ∈ [ l , r ] i\in[l,r] i[l,r] 執行 b i ← b i × v b_i\gets b_i\times v bi?bi?×v.
  • assign ? ( l , r , v ) \operatorname{assign}(l,r,v) assign(l,r,v):對每個 i ∈ [ l , r ] i\in[l,r] i[l,r] 執行 c i ← v c_i\gets v ci?v.
  • query ? ( l , r ) \operatorname{query}(l,r) query(l,r):求 ∑ i = l r a i \sum\limits_{i=l}^r a_i i=lr?ai? ∑ i = l r b i \sum\limits_{i=l}^r b_i i=lr?bi? ∑ i = l r c i \sum\limits_{i=l}^r c_i i=lr?ci?的值,對 998244353 998244353 998244353 取模.

Limitations

1 ≤ n , m ≤ 2.5 × 1 0 5 1\le n,m\le 2.5\times 10^5 1n,m2.5×105
0 ≤ a i , b i , c i , v < 998244353 0\le a_i,b_i,c_i,v<998244353 0ai?,bi?,ci?,v<998244353
1 ≤ l ≤ r ≤ n 1\le l\le r\le n 1lrn
5 s , 500 MB 5\text{s},500\text{MB} 5s,500MB

Solution

顯然需要矩陣,由于要加常數,每個節點維護矩陣 [ a , b , c , 1 ] \begin{bmatrix}a,b,c,1\end{bmatrix} [a,b,c,1?].
然后考慮用矩陣表達修改,由左行右列的口訣,顯然有:

  • [ a , b , c , 1 ] × [ 1 , 0 , 0 , 0 1 , 1 , 0 , 0 0 , 0 , 1 , 0 0 , 0 , 0 , 1 ] = [ a + b , b , c , 1 ] \begin{bmatrix}a,b,c,1\end{bmatrix}\times \begin{bmatrix}1,0,0,0\\ 1,1,0,0\\0,0,1,0\\0,0,0,1\end{bmatrix}=\begin{bmatrix}a+b,b,c,1\end{bmatrix} [a,b,c,1?]× ?1,0,0,01,1,0,00,0,1,00,0,0,1? ?=[a+b,b,c,1?]
  • [ a , b , c , 1 ] × [ 1 , 0 , 0 , 0 0 , 1 , 0 , 0 0 , 1 , 1 , 0 0 , 0 , 0 , 1 ] = [ a , b + c , c , 1 ] \begin{bmatrix}a,b,c,1\end{bmatrix}\times \begin{bmatrix}1,0,0,0\\ 0,1,0,0\\0,1,1,0\\0,0,0,1\end{bmatrix}=\begin{bmatrix}a,b+c,c,1\end{bmatrix} [a,b,c,1?]× ?1,0,0,00,1,0,00,1,1,00,0,0,1? ?=[a,b+c,c,1?]
  • [ a , b , c , 1 ] × [ 1 , 0 , 1 , 0 0 , 1 , 0 , 0 0 , 0 , 1 , 0 0 , 0 , 0 , 1 ] = [ a , b , c + a , 1 ] \begin{bmatrix}a,b,c,1\end{bmatrix}\times \begin{bmatrix}1,0,1,0\\ 0,1,0,0\\0,0,1,0\\0,0,0,1\end{bmatrix}=\begin{bmatrix}a,b,c+a,1\end{bmatrix} [a,b,c,1?]× ?1,0,1,00,1,0,00,0,1,00,0,0,1? ?=[a,b,c+a,1?]
  • [ a , b , c , 1 ] × [ 1 , 0 , 0 , 0 0 , 1 , 0 , 0 0 , 0 , 1 , 0 v , 0 , 0 , 1 ] = [ a + v , b , c , 1 ] \begin{bmatrix}a,b,c,1\end{bmatrix}\times \begin{bmatrix}1,0,0,0\\ 0,1,0,0\\0,0,1,0\\v,0,0,1\end{bmatrix}=\begin{bmatrix}a+v,b,c,1\end{bmatrix} [a,b,c,1?]× ?1,0,0,00,1,0,00,0,1,0v,0,0,1? ?=[a+v,b,c,1?]
  • [ a , b , c , 1 ] × [ 1 , 0 , 0 , 0 0 , v , 0 , 0 0 , 0 , 1 , 0 0 , 0 , 0 , 1 ] = [ a , b × v , c , 1 ] \begin{bmatrix}a,b,c,1\end{bmatrix}\times \begin{bmatrix}1,0,0,0\\ 0,v,0,0\\0,0,1,0\\0,0,0,1\end{bmatrix}=\begin{bmatrix}a,b\times v,c,1\end{bmatrix} [a,b,c,1?]× ?1,0,0,00,v,0,00,0,1,00,0,0,1? ?=[a,b×v,c,1?]
  • [ a , b , c , 1 ] × [ 1 , 0 , 0 , 0 0 , 1 , 0 , 0 0 , 0 , 0 , 0 0 , 0 , v , 1 ] = [ a , b , v , 1 ] \begin{bmatrix}a,b,c,1\end{bmatrix}\times \begin{bmatrix}1,0,0,0\\ 0,1,0,0\\0,0,0,0\\0,0,v,1\end{bmatrix}=\begin{bmatrix}a,b,v,1\end{bmatrix} [a,b,c,1?]× ?1,0,0,00,1,0,00,0,0,00,0,v,1? ?=[a,b,v,1?]

由于矩陣乘法滿足結合律,可以用線段樹維護,維護每個節點的矩陣與標記(也是一個矩陣),修改操作直接乘上對應矩陣,查詢操作求矩陣和即可.

需要注意幾點:

  • 要初始化為單位矩陣的地方,不要忘記初始化.
  • 矩陣乘法時,不計算一直為 0 0 0 的位置.
  • 如果是單位矩陣就不下傳.

Code

3.85 KB , 27.95 s , 80.72 MB (in total, C++20 with O2) 3.85\text{KB},27.95\text{s},80.72\text{MB}\;\texttt{(in total, C++20 with O2)} 3.85KB,27.95s,80.72MB(in?total,?C++20?with?O2)

#include <bits/stdc++.h>
using namespace std;using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;template<class T>
bool chmax(T &a, const T &b){if(a < b){ a = b; return true; }return false;
}template<class T>
bool chmin(T &a, const T &b){if(a > b){ a = b; return true; }return false;
}constexpr int mod = 998244353;
inline int add(int x, int y) {return x + y >= mod ? x + y - mod : x + y; }
namespace matrix {struct Mat {int mat[4][4];inline Mat(int _e = 1) { memset(mat, 0, sizeof mat); mat[0][0] = mat[1][1] = mat[2][2] = mat[3][3] = _e;}inline int* operator[](int i) { return mat[i]; }inline const int* operator[](int i) const { return mat[i]; }};inline Mat operator+(const Mat& x, const Mat& y) {Mat z(0);for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++) z[i][j] = add(x[i][j], y[i][j]);return z;}inline Mat operator*(const Mat& x, const Mat& y) {Mat z(0);for (int i = 0; i < 4; i++)for (int k = 0; k < 4; k++) {if (!x[i][k]) continue;for (int j = 0; j < 4; j++) {if (!y[k][j]) continue;z[i][j] = (z[i][j] + 1LL * x[i][k] * y[k][j]) % mod;}}return z;}inline bool operator==(const Mat& x, const Mat& y) {for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)if (x[i][j] != y[i][j]) return false;return true;}
}
using matrix::Mat;namespace seg_tree {struct Node {int l, r;Mat val, tag;};inline int ls(int u) { return 2 * u + 1; }inline int rs(int u) { return 2 * u + 2; }struct SegTree {vector<Node> tr;inline SegTree() {}inline SegTree(const vector<Mat>& a) {const int n = a.size();tr.resize(n << 1);build(0, 0, n - 1, a);}inline void pushup(int u, int mid) {tr[u].val = tr[ls(mid)].val + tr[rs(mid)].val;}inline void apply(int u, const Mat& mat) {tr[u].val = tr[u].val * mat;tr[u].tag = tr[u].tag * mat;}inline void pushdown(int u, int mid) {if (tr[u].tag == Mat()) return;apply(ls(mid), tr[u].tag);apply(rs(mid), tr[u].tag);tr[u].tag = Mat();}inline void build(int u, int l, int r, const vector<Mat>& a) {tr[u].l = l, tr[u].r = r;if (l == r) {tr[u].val = a[l];return;}const int mid = (l + r) >> 1;build(ls(mid), l, mid, a);build(rs(mid), mid + 1, r, a);pushup(u, mid);}inline void modify(int u, int l, int r, const Mat& mat) {if (l <= tr[u].l && tr[u].r <= r) return apply(u, mat);const int mid = (tr[u].l + tr[u].r) >> 1;pushdown(u, mid);if (l <= mid) modify(ls(mid), l, r, mat);if (r > mid) modify(rs(mid), l, r, mat);pushup(u, mid); }inline Mat query(int u, int l, int r) {if (l <= tr[u].l && tr[u].r <= r) return tr[u].val;const int mid = (tr[u].l + tr[u].r) >> 1;Mat res = Mat(0);pushdown(u, mid);if (l <= mid) res = res + query(ls(mid), l, r);if (r > mid) res = res + query(rs(mid), l, r);return res;}};
}
using seg_tree::SegTree;signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int n; scanf("%d", &n);vector<Mat> a(n);for (int i = 0; i < n; i++) {scanf("%d %d %d", &a[i][0][0], &a[i][0][1], &a[i][0][2]);a[i][0][3] = 1;}SegTree sgt(a);int m; scanf("%d", &m);for (int i = 0, op, l, r; i < m; i++) {scanf("%d %d %d", &op, &l, &r), l--, r--;if (op == 7) {auto mat = sgt.query(0, l, r);printf("%d %d %d\n", mat[0][0], mat[0][1], mat[0][2]);}else {auto mat = Mat();if (op == 1) mat[1][0] = 1;if (op == 2) mat[2][1] = 1;if (op == 3) mat[0][2] = 1;if (op == 4) scanf("%d", &mat[3][0]);if (op == 5) scanf("%d", &mat[1][1]);if (op == 6) scanf("%d", &mat[3][2]), mat[2][2] = 0;sgt.modify(0, l, r, mat);}}return 0;
}

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

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

相關文章

免費送源碼:Java+ssm+MySQL SpringBoot社區配送服務系統小程序 計算機畢業設計原創定制

摘要 隨著科學技術的飛速發展&#xff0c;社會的方方面面、各行各業都在努力與現代的先進技術接軌&#xff0c;通過科技手段來提高自身的優勢&#xff0c;社區當然也不例外。社區配送服務系統小程序是以實際運用為開發背景&#xff0c;運用軟件工程原理和開發方法&#xff0c;…

SQL語句(一)—— DDL

目錄 一、SQL 基礎知識 &#xff08;一&#xff09;SQL 通用語法 &#xff08;二&#xff09;SQL 分類 二、DDL —— 數據庫操作 1、查詢所有數據庫 2、查詢當前數據庫 3、創建數據庫 4、刪除數據庫 5、切換數據庫 三、DDL —— 表操作 &#xff08;一&#xff09;查…

【Android】界面布局-線性布局LinearLayout-例子

線性布局&#xff08;LinearLayout&#xff09;是一種重要的界面布局中&#xff0c;也是經常使用到的一種界面布局 ? 在線性布局中&#xff0c;所有的子元素都按照垂直或水平的順序在界面上排列 ?如果垂直排列&#xff0c;則每行僅包含一個界面元素 ?如果水平排列&…

leetcode數組-長度最小的子數組

題目 題目鏈接&#xff1a;https://leetcode.cn/problems/minimum-size-subarray-sum/ 給定一個含有 n個正整數的數組和一個正整數 target** 。** 找出該數組中滿足其總和大于等于target的長度最小的 子數組 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其長度**…

一周學會Pandas2 Python數據處理與分析-Jupyter Notebook安裝

鋒哥原創的Pandas2 Python數據處理與分析 視頻教程&#xff1a; 2025版 Pandas2 Python數據處理與分析 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili Jupyter (Project Jupyter | Home&#xff09;項目是一個非營利性開源項目&#xff0c;于2014年由IPython項目中誕生…

前端頁面鼠標移動監控(鼠標運動、鼠標監控)鼠標節流處理、throttle、限制觸發頻率(setTimeout、clearInterval)

文章目錄 使用lodashjs庫手動實現節流&#xff08;通過判斷之前設定的定時器setTimeout是否存在&#xff09; 使用lodashjs庫 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Com…

java流程控制04:if選擇結構

選擇結構 if單選擇結構 if雙選擇結構 if多選擇結構 嵌套的if結構 switch多選擇結構 if單選擇結構 我們很多時候需要去判斷一個東西是否可行&#xff0c;然后我們才去執行&#xff0c;這樣一個過程在程序中用if語句來表示 語法&#xff1a; if(布爾表達式){//如果布爾表達…

在uniapp中,video比普通的標簽層級高解決問題

<view style"position: relative;"><video style"position: absolute;z-index:-1"></video><view style"position: absolute;z-index:999"></view> </view> 上面代碼并沒有解決view的層級比video高的問題&…

基于R語言與MaxEnt的物種分布建模全流程解析:從算法優化到科研制圖實戰

隨著全球氣候變化與生物多樣性保護需求的加劇&#xff0c;物種分布模型&#xff08;Species Distribution Model, SDM&#xff09;已成為生態學、保護生物學研究的核心工具。MaxEnt模型憑借其?對小樣本數據的強適應性?和?環境變量非線性關系的解析能力?&#xff0c;成為SDM…

DPDI版本升級說明

Dispatch PDI v2.0.3版本升級說明 自Dispatch PDI社區版全新版本V2.0.0于2025 年3月25日發布以來&#xff0c;我們始終緊密關注用戶動態&#xff0c;并全力協助用戶線上完成從V0.0.4到V2.0.0的遷移工作。在短短一周內&#xff0c;我們成功助力約90%的用戶完成了遷移。在此期間…

大鉦資本押注儒拉瑪特全球業務,累計交付超2500條自動化生產線儒拉瑪特有望重整雄風,我以為它破產倒閉了,擔心很多非標兄弟們失業

1. 交易概況 時間與主體:大鉦資本于2025年4月1日正式宣布完成對儒拉瑪特自動化技術(蘇州)有限公司及其全球子公司和關聯企業的收購。交易通過大鉦資本旗下美元基金設立的儒拉瑪特(新加坡)公司作為控股主體進行,交易金額未披露。 收購范圍:包括儒拉瑪特亞太、歐洲、北美等…

LabVIEW 調用 Python 函數

此程序是 LabVIEW 調用 Python 函數實現雙精度數相加的典型示例。通過 LabVIEW 搭建交互框架&#xff0c;借助 “Open Python Session” 創建 Python 代碼運行環境&#xff0c;定位 Python 模塊路徑后調用 “Add” 函數&#xff0c;最終實現數據處理并關閉會話。整個流程展現了…

基于SpringBoot的“考研學習分享平臺”的設計與實現(源碼+數據庫+文檔+PPT)

基于SpringBoot的“考研學習分享平臺”的設計與實現&#xff08;源碼數據庫文檔PPT) 開發語言&#xff1a;Java 數據庫&#xff1a;MySQL 技術&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系統展示 系統總體功能結構圖 局部E-R圖 系統首頁界面 …

恒盾C#混淆加密衛士 - 混淆加密保護C#程序

對于大部分C#開發者來說&#xff0c;寫完代碼點個發布就完事兒了&#xff0c;但你可能不知道——用記事本都能扒開你編譯好的程序&#xff01;像dnSpy這類反編譯工具&#xff0c;分分鐘能把你的EXE/DLL變回原汁原味的源代碼&#xff0c;商業機密赤裸裸曝光不說&#xff0c;競爭…

selectdb修改表副本

如果想修改doris&#xff08;也就是selectdb數據庫&#xff09;表的副本數需要首先確定是否分區表&#xff0c;當前沒有數據字典得知哪個表是分區的&#xff0c;只能先show partitions看結果 首先&#xff0c;副本數不應該大于be節點數 其次&#xff0c;修改期間最好不要跑業務…

【嵌入式-stm32電位器控制以及旋轉編碼器控制LED亮暗】

嵌入式-stm32電位器控制LED亮暗 任務1代碼1Key.cKey.hTimer.cTimer.hPWM.cPWM.hmain.c 實驗現象1任務2代碼2Key.cKey.hmain.c 實驗現象2問題與解決總結 源碼框架取自江協科技&#xff0c;在此基礎上做擴展開發。 任務1 本文主要介紹利用stm32f103C8T6實現電位器控制PWM的占空比…

圖撲可視化點亮智慧城市垃圾分類新未來

圖撲基于 HT 開發的智慧城市廢棄物可視化管理系統&#xff0c;通過智能感知與三維可視化技術&#xff0c;構建全流程數字化監管平臺。系統實現固體廢物從源頭投放到終端處置的全程可視化追蹤&#xff0c;提供智能收運路徑規劃與資源回收管理方案&#xff0c;助力城市環境治理向…

Elasticsearch安全加固指南:啟用登錄認證與SSL加密

在之前文章中我們介紹了Elasticsearch安全與權限控制&#xff0c;本篇文章我們將詳細介紹 啟用登錄認證與SSL加密實踐配置操作 。 1 為什么需要安全加固&#xff1f; Elasticsearch默認不啟用安全功能&#xff0c;會導致以下風險&#xff1a; 未授權訪問&#xff1a;任何人都能…

前端知識點---本地存儲(javascript)

localStorage 是瀏覽器提供的一個 本地存儲 API&#xff0c;可以在用戶的瀏覽器中存儲數據&#xff0c;數據不會隨頁面刷新而丟失。 1. 基本用法 (1) 存儲數據&#xff08;setItem&#xff09; localStorage.setItem("username", "zhangsan");存儲 “use…

神經網絡能不能完全擬合y=x2 ???

先說結論&#xff1a;關鍵看激活函數的選擇 ReLU神經網絡對非線性函數的擬合分析 ReLU神經網絡對非線性函數&#xff08;如 y x 2 y x^2 yx2&#xff09;的擬合只能是逼近&#xff0c;而無法實現數學意義上的完全重合。這一結論源于ReLU的分段線性本質與目標函數的非線性結…