【BZOJ 3326】[Scoi2013]數數 數位dp+矩陣乘法優化

挺好的數位dp……
先說一下我個人的做法:
經過觀察,發現這題按照以往的思路從后往前遞增,不怎么好推,然后我就大膽猜想,從前往后推,發現很好推啊,維護四個變量,從開始位置到現在有了i個數
f[i]:所有數的所有未包含最后一位的子串的和
s[i]:所有數的所有后綴子串的和
c[i]:所有數的所有后綴子串的個數
n[i]:所有數共有多少個
他們的轉移依次是(k為進制數)
f[i]=f[i-1]*k+s[i-1]*k
s[i]=s[i-1]*k*k+c[i-1]*k*(k-1)/2+n[i-1]*k*(k-1)/2
c[i]=c[i-1]*k+n[i-1]*k
n[i]=n[i-1]*k
我們發現對于最高位低于上界的數,我們可以在確定最高位上是1~9之后用上面的轉移一遍O(n)dp算出來.如果最高位等于上界的話,我們的轉移不太一樣,但是也只不過是把某些k改為了這一位的上屆,而且如果本位未達到上屆,往后轉移還是老樣子,然而每次都要從前往后走一遍,會T,不過,這很明顯是個可以用矩陣乘法優化的dp,因為他的轉移方式每次都一樣,所以我們就可以加速了,然而這是4*4的矩陣再加上一個log,吃不消啊,但是我們可以預處理轉移i(1<=i<=max(n,m))次的矩陣,這樣就可以做到O(4^3*n)了,又因為這個矩陣是個上三角矩陣,所以我們加一些矩陣乘法時的優化就可以有有著一個10左右常數的O(n)的做法了,我們解決了這道題!!!
現在說一下別人的做法:
A掉之后,去網上看了看別人的題解,發現從后往前遞增并不是不可以,而且根本就沒有人從前往后推,更沒有任何人的做法跟矩陣乘法有半點關系……
他們就是從后往前遞增,推出來一個關于k的次冪的式子,通過預處理k的次冪,加上對于上界的處理來遞推……
他們的做法基本上都是O(n)的,但是跑得和我差不多……

#include <cstdio>
#include <cstring>
#include <algorithm>
char xB[(1<<15)+10],*xS,*xT;
#define gtc (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)
template <typename _t>
inline void read(_t &x){register char ch=gtc;bool ud=false;for(x=0;ch<'0'||ch>'9';ch=gtc)if(ch=='-')ud=true;for(;ch>='0'&&ch<='9';x=(x<<1)+(x<<3)+ch-'0',ch=gtc);if(ud)x=-x;
}
typedef long long LL;
const int P=20130427;
const int N=100010;
int a[4][4],b[4],s[N][4][4],temp_a[4][4],temp_b[4],c[4],d[4];
inline void get(int x[][4],int y){memset(temp_a,0,sizeof(a));register int i,j,k;for(i=0;i<4;++i)for(j=0;j<4;++j)if(a[i][j])for(k=0;k<4;++k)if(x[j][k])temp_a[i][k]=(temp_a[i][k]+(LL)x[j][k]*a[i][j])%P;memcpy(s[y],temp_a,sizeof(s[y]));
}
inline void run(int x[][4]){memset(temp_b,0,sizeof(temp_b));register int i,j;for(i=0;i<4;++i)for(j=0;j<4;++j)if(x[i][j])temp_b[i]=(temp_b[i]+(LL)x[i][j]*d[j])%P;memcpy(c,temp_b,sizeof(c));
}
int bit,digit[N],k,n,m,len;
inline int calc(){int ans=0,i;d[3]=0,d[2]=(LL)k*(k-1)/2%P,d[1]=k-1,d[0]=k-1;for(i=1;i<bit;++i)run(s[i-1]),ans=(ans+c[3]+c[2])%P;memset(b,0,sizeof(b)),b[0]=1;for(i=bit;i>0;--i){d[0]=((LL)b[0]*(digit[i]-(i==bit))%P);d[1]=((LL)b[1]*(digit[i]-(i==bit))+d[0])%P;d[2]=((LL)k*b[2]%P*(digit[i]-(i==bit))+(LL)b[1]*((LL)digit[i]*(digit[i]-1)/2%P)+(LL)b[0]*((LL)digit[i]*(digit[i]-1)/2%P))%P;d[3]=((LL)b[3]*(digit[i]-(i==bit))+(LL)b[2]*(digit[i]-(i==bit)))%P;run(s[i-1]);ans=(ans+c[3]+c[2])%P;b[3]=(b[3]+b[2])%P;b[2]=((LL)k*b[2]+(LL)(b[1]+b[0])*digit[i])%P;++b[1];}return (ans+b[3]+b[2])%P;
}
int main(){read(k);int i,j,ans=0;a[3][3]=k,a[3][2]=k;a[2][2]=(LL)k*k%P,a[2][1]=((LL)k*(k-1)/2)%P,a[2][0]=((LL)k*(k-1)/2)%P;a[1][1]=k,a[1][0]=k;a[0][0]=k;s[0][0][0]=s[0][1][1]=s[0][2][2]=s[0][3][3]=1;for(read(n),i=n;i>0;--i)read(digit[i]);read(m),len=std::max(n,m);for(i=1;i<=len;++i)get(s[i-1],i);if(n==1)ans=(ans-(LL)digit[1]*(digit[1]-1)/2%P+P)%P;else{for(--digit[1],i=1;i<=n;++i)if(digit[i]<0)digit[i]+=k,--digit[i+1];else break;while(digit[n]==0)--n;bit=n,ans=(ans-calc()+P)%P;}for(i=m;i>0;--i)read(digit[i]);if(m==1)ans=(ans+(LL)digit[1]*(digit[1]+1)/2%P)%P;else bit=m,ans=(ans+calc())%P;printf("%d\n",ans);return 0;
}

?

轉載于:https://www.cnblogs.com/TSHugh/p/8475491.html

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

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

相關文章

zookeeper偽集群(在一臺機器上集群)

2019獨角獸企業重金招聘Python工程師標準>>> 創建一下的目錄結構zookeeper-3.4.10是你下載的zookeeper的解壓包 /zookeeper_cluster----/server_one|---/data|myid(文件)|---/datalog|---/zookeeper-3.4.10|---/bin|---/conf|---zoo.cfg|---..... |---/....----/ser…

mongo的php查詢,使用PHP進行簡單查詢的mongo查詢速度慢

我有一個非常簡單的使用PHP執行的Mongo Query。我相信查詢執行得非常快&#xff0c;因為當我在終端上運行它時&#xff0c;它幾乎可以立即完成&#xff0c;并且當我解釋()時&#xff0c;它表明它正在1-2ms內執行。但是&#xff0c;當我去迭代游標并將內容放入數組時&#xff0c…

順序存儲結構和鏈式存儲結構的優缺點

&#xff08;一&#xff09;順序存儲結構和鏈式存儲結構的優缺點比較&#xff0c;以及使用情況。 1 優缺點 ① 順序存儲時&#xff0c;相鄰數據元素的存放地址也相鄰&#xff08;邏輯與物理統一&#xff09;&#xff1b;要求內存中可用存儲單元的地址必須是連續的。 優點&…

大話軟件開發與開車的共同點

昨天路上開車&#xff0c;突然有了這個想法&#xff0c;做軟件開發與開車&#xff0c;竟然有這么多的相似之處&#xff0c;大致整理了一下思路&#xff0c;和大家分享一下。 一、目的 開車的目的有3個&#xff0c;第一是為了讓自己到底目的地(上班族)&#xff0c;第二是為了兜…

Spring核心接口之Ordered

一、Ordered接口介紹Spring中提供了一個Ordered接口。從單詞意思就知道Ordered接口的作用就是用來排序的。Spring框架是一個大量使用策略設計模式的框架&#xff0c;這意味著有很多相同接口的實現類&#xff0c;那么必定會有優先級的問題。于是Spring就提供了Ordered這個接口&a…

將本地代碼上傳至github

注冊github賬號 https://github.com/ 安裝git工具 https://git-for-windows.github.io 1.在github中創建一個項目 2.填寫相應信息&#xff0c;點擊create Repository name: 倉庫名稱 Description(可選): 倉庫描述介紹 Public, Private : 倉庫權限&#xff08;公開共享&#xff…

禪道 php api,云禪道有API的方式可以獲取數據嗎

api相關手冊&#xff1a;api接口查看&#xff0c;可以本地搭建和云禪道相同版本的禪道&#xff0c;然后admin 后臺 二次開發 api&#xff0c;可以查看接口列表。api調用步驟PATH_INFO方式1、訪問 http://x.com/api-getsessionid.json獲取禪道session信息2、使用上一步獲取的ses…

鏈表的頭結點和尾節點的用處

某些情況下設置尾指針的好處 尾指針是指向終端結點的指針&#xff0c;用它來表示單循環鏈表可以使得查找鏈表的開始結點和終端結點都很方便&#xff0c;設一帶頭結點的單循環鏈表&#xff0c;其尾指針為rear&#xff0c;則開始結點和終端結點的位置分別是rear->next->ne…

經驗從哪里來?從痛苦中來!

1 剛才發博客&#xff0c;寫的幾百字丟失&#xff0c;讓我知道下次一定要在記事本里寫好&#xff0c;再復制過來&#xff0c;避免丟失了 2 程序忘記備份&#xff0c;辛苦一個多月的東西沒有了&#xff0c;只能找到1月前的版本&#xff0c;讓我知道了&#xff0c;重要的東西必須…

oracle 加全文索引,Oracle創建全文索引

1、創建表空間&#xff0c;有必要將物理文件設置大一些2、創建基于這個表空間的用戶3、創建需要建立全文索引的表4、用管理員帳戶為使用這用戶開發ctx_ddl權限grant execute on ctx_ddl to useer;5、創建適合的lexer(解析器)exec ctx_ddl.create_references(my_lexer,basic_le…

機器視覺系統需要考慮的十個問題

為了使用戶在選擇一款機器視覺系統時應該考慮的關鍵的、基本的特性方面提供指導。下面是選擇一款機器視覺系統時要優先考慮的十個方面&#xff1a; 1. 定位器 對象或特征的精確定位是一個檢測系統或由視覺引導的運動系統的重要功能。傳統的物體定位采用的是灰度值校正來識別物體…

嚴蔚敏數據結構:鏈表實現一元多項式相加

一、基本概念 1、多項式pn(x)可表示成: pn(x)a0a1xa2x2…anxn。 listP{&#xff08;a0&#xff0c;e0&#xff09;&#xff0c;(a1&#xff0c;e1)&#xff0c;(a2&#xff0c;e2)&#xff0c;…&#xff0c;(an&#xff0c;en) }。在這種線性表描述中&#xff0c;各個結點…

Java二十三設計模式之------工廠方法模式

一、工廠方法模式&#xff08;Factory Method&#xff09; 工廠方法模式有三種 1、普通工廠模式&#xff1a;就是建立一個工廠類&#xff0c;對實現了同一接口的一些類進行實例的創建。首先看下關系圖&#xff1a; 舉例如下&#xff1a;&#xff08;我們舉一個發送郵件和短信的…

無法轉化為項目財富的技術或功能就是垃圾

技術人員可能有個習慣&#xff0c;也可以叫通病&#xff0c;發現一個新技術&#xff0c;或者新的想法&#xff0c;會把某個現有的東西做的更好&#xff0c;或者可以增加某個功能讓系統看上去更完美。 如果這是一個產品&#xff0c;那么大家都會鼓勵你去做&#xff0c;如果我們…

ibatis oracle function,IBATIS調用oracle function(函數)的步驟實例

IBATIS調用oracle function(函數)的方法實例引用create or replace function getClassifiedCode(p_planCode in varchar2 -- 險種代碼,p_usageAttributeCode in varchar2 -- 使用性質代碼,p_ownershipAttributeCode in varchar2 -- 所屬性質代碼,p_vehicleTypeCode in varchar2…

一元多項式乘法算法

我認為大致算法應該是這樣的: 首先準備一個空的鏈表L。利用第一個多項式的的指針所指的節點數值乘以多項式二的每一項&#xff0c;將結果保存在鏈表L中。 然后將指向該節點的指針后移到下一個節點繼續進行乘法運算&#xff0c;將所得結果加到L中&#xff08;這個操作已經在一…

堆以及stl堆的使用

概念 性質: 1.堆是一顆完全二叉樹&#xff0c;用數組實現。 ???2.堆中存儲數據的數據是局部有序的。 最大堆&#xff1a;1.任意一個結點存儲的值都大于或等于其任意一個子結點中存儲的值。 ?????2.根結點存儲著該樹所有結點中的最大值。 最小堆&#xff1a;1.任意一個結…

讀【36歲IT老人再次隨筆】的讀后感,你會哪些計算機語言?

論壇首頁一篇&#xff1a;社區“揭穿最大謊言”事件 &#xff0c; 我看了&#xff0c;也順便看了里面另一位仁兄的【36歲IT老人再次隨筆】 其中關鍵的地方就是一個例子&#xff1a;你會哪些計算機語言&#xff1f; 這個問題很有意思&#xff0c;確實如網友回復里說到的&#xf…

php接收vue請求數據axios,詳解vue axios用post提交的數據格式

Content-type的幾種常見類型一、是什么&#xff1f;是Http的實體首部字段&#xff0c;用于說明請求或返回的消息主體是用何種方式編碼&#xff0c;在request header和response header里都存在。二、幾個常用類型&#xff1a;1、application/x-www-form-urlencoded這應該是最常見…

數據結構中的邏輯結構簡介

數據的邏輯結構是對數據之間關系的描述&#xff0c;有時就把邏輯結構簡稱為數據結構。邏輯結構形式地定義為&#xff08;K&#xff0c;R&#xff09;&#xff08;或&#xff08;D&#xff0c;S&#xff09;&#xff09;&#xff0c;其中&#xff0c;K是數據元素的有限集&#x…