轉載請註明原文地址http://www.cnblogs.com/LadyLex/p/8490222.html html
以前學數位dp的時候底子沒打紮實ios
虛的要死數組
此次正好有時間……刷了刷以前沒作的題目ide
感受本身腦洞不太夠……比較經典的題或者見過的相似模型就能本身推出來,可是沒有見過的模型就虛的要死(好比二進制數位DP)優化
感謝WQ的幫助,讓我對數位DP的理解逐漸加深ui
那麼咱們總結一下此次作的題目……spa
記憶化搜索便可,水爆3d
1 #include <cstring> 2 #include <cstdio> 3 using namespace std; 4 #define RG register 5 #define LL long long 6 int bin[15],cnt; 7 LL poww[15],f[12][10][3][3][2][2]; 8 inline int min(int a,int b){return a<b?a:b;} 9 inline int max(int a,int b){return a>b?a:b;} 10 inline LL dfs(int st,int pre,int comb,int maxcomb,bool have8,bool have4,bool limit) 11 { 12 if(st==0)return maxcomb==3; 13 if(!limit&&f[st][pre][comb][maxcomb][have8][have4]!=-1) 14 return f[st][pre][comb][maxcomb][have8][have4]; 15 LL ret=0; 16 RG int i,tmp,lim=(limit)?bin[st]:10; 17 for(i=0;i<lim;++i) 18 { 19 tmp=min((pre==i)?comb+1:1,3); 20 if(i==4) 21 { 22 if(!have8)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),0,1,0); 23 } 24 else if(i==8) 25 { 26 if(!have4)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),1,0,0); 27 } 28 else ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),have8,have4,0); 29 } 30 if(limit) 31 { 32 tmp=min((pre==i)?comb+1:1,3); 33 if(i==4) 34 { 35 if(!have8)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),0,1,1); 36 } 37 else if(i==8) 38 { 39 if(!have4)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),1,0,1); 40 } 41 else ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),have8,have4,1); 42 } 43 if(!limit)f[st][pre][comb][maxcomb][have8][have4]=ret; 44 return ret; 45 } 46 inline LL calc(LL len) 47 { 48 LL ret=0;cnt=0; 49 while(len)bin[++cnt]=len%10,len/=10; 50 for(RG int i=1;i<bin[11];++i)ret+=dfs(10,i,1,1,i==8,i==4,0); 51 return ret+dfs(10,bin[11],1,1,bin[11]==8,bin[11]==4,1); 52 } 53 int main() 54 { 55 LL l,r,ans;RG int i; 56 for(poww[0]=i=1;i<=12;++i)poww[i]=poww[i-1]*9; 57 scanf("%lld%lld",&l,&r); 58 memset(f,-1,sizeof(f)),ans=calc(r); 59 if(l>1e10)ans-=calc(l-1); 60 printf("%lld\n",ans); 61 }
僞裝他是數位dp的小模擬code
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define RG register 5 #define LL long long 6 int br[12],bl[12],lr,ll,_10[12]; 7 int main() 8 { 9 RG int pos,i,j,l,r,tmp,t,ans; 10 scanf("%d",&t); 11 for(_10[1]=1,i=2;i<=10;++i)_10[i]=_10[i-1]*10; 12 while(t--) 13 { 14 scanf("%d%d",&l,&r),--l; 15 ll=lr=0; 16 tmp=r;while(tmp)br[++lr]=tmp%10,tmp/=10; 17 tmp=l;while(tmp)bl[++ll]=tmp%10,tmp/=10; 18 if(lr!=ll) 19 { 20 if(l<5*_10[ll])ans=5*_10[ll]; 21 else if(5*_10[ll+1]<=r)ans=5*_10[ll+1]; 22 else if(bl[ll]==9)ans=_10[ll+1]; 23 else ans=_10[ll]*(bl[ll]+1); 24 } 25 else 26 { 27 pos=ll;ans=0; 28 while(bl[pos]==br[pos]&&pos)ans=ans*10+bl[pos],--pos; 29 if(pos) 30 { 31 if(bl[pos]<5&&5<=br[pos])ans=(ans*10+5)* _10[pos]; 32 else ans=(ans*10+bl[pos]+1)* _10[pos]; 33 } 34 } 35 printf("%d\n",ans); 36 } 37 }
從低位往高位DP,帶個組合數亂搞,比較水,沒有打htm
兩邊同時異或一下x,而後因爲異或是不進位的加法,因此發現性質是沒有相鄰的1,dp便可
1 #include <cstring> 2 #include <cstdio> 3 using namespace std; 4 #define mod 1000000007 5 #define RG register 6 #define LL long long 7 namespace work1 8 { 9 LL f[64][2];int bin[64],len; 10 inline void init() 11 { 12 f[1][0]=1,f[1][1]=1; 13 for(RG int i=2;i<=62;++i) 14 f[i][0]=f[i-1][0]+f[i-1][1],f[i][1]=f[i-1][0]; 15 } 16 inline LL dfs(int st,int pre,bool lim) 17 { 18 if(st==0)return 1; 19 if(!lim)return pre?f[st][0]:f[st][0]+f[st][1]; 20 if(bin[st]) 21 return pre?dfs(st-1,0,0):(dfs(st-1,0,0)+dfs(st-1,1,1)); 22 return dfs(st-1,0,1); 23 } 24 inline LL work(LL n) 25 { 26 if(!n)return 0; 27 len=0;while(n)bin[++len]=n&1,n>>=1; 28 return dfs(len-1,0,0)+dfs(len-1,1,1)-1; 29 } 30 } 31 namespace work2 32 { 33 struct matrix 34 { 35 int a[4][4]; 36 inline void clear(){memset(a,0,sizeof(a));} 37 inline void init(){memset(a,0,sizeof(a));for(RG int i=0;i<4;++i)a[i][i]=1;} 38 inline matrix operator * (const matrix &b)const 39 { 40 RG int i,j,k; 41 matrix c;c.clear(); 42 for(i=0;i<4;++i) 43 for(k=0;k<4;++k)if(a[i][k]) 44 for(j=0;j<4;++j)if(b.a[k][j]) 45 c.a[i][j]=(c.a[i][j]+(LL)a[i][k]*b.a[k][j])%mod; 46 return c; 47 } 48 inline void print() 49 { 50 for(RG int i=0;i<4;++i,printf("\n")) 51 for(RG int j=0;j<4;++j) 52 printf("%d ",a[i][j]); 53 } 54 }d,t; 55 inline void init() 56 { 57 d.clear(),d.a[0][0]=d.a[0][1]=d.a[0][2]=d.a[1][0]=d.a[1][3]=1; 58 } 59 inline matrix quick_mod(matrix di,LL mi) 60 { 61 matrix ret;ret.init(); 62 for(;mi;mi>>=1,di=di*di)if(mi&1)ret=ret*di; 63 return ret; 64 } 65 inline int work(LL n) 66 { 67 t.clear(),t.a[0][0]=t.a[0][1]=1,t=t*quick_mod(d,n); 68 return t.a[0][0]; 69 } 70 } 71 int main() 72 { 73 RG int i,j,t;LL n; 74 scanf("%d",&t); 75 work1::init(),work2::init(); 76 while(t--) 77 scanf("%lld",&n),printf("%lld\n%d\n",work1::work(n),work2::work(n)); 78 }
打表發現數位之和不多,枚舉數位之和,可是我沒想到dp的定義……
而後看了一下題解的數組定義,難度適中吧……沒有那麼難,可是本身仍是沒想出來
那個維護當前值而後每次cur=cur×10+i的很巧妙,沒想出來……
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define RG register 6 #define LL long long 7 int bin[20]; 8 inline int min(int a,int b){return a<b?a:b;} 9 inline int max(int a,int b){return a>b?a:b;} 10 int mod,mark[20][163][163][2]; 11 LL f[20][163][163][2]; 12 inline LL dfs(int st,int sum,int cur,bool lim) 13 { 14 if(st==0)return cur==0&&sum==0; 15 if(mark[st][sum][cur][lim]==mod)return f[st][sum][cur][lim]; 16 mark[st][sum][cur][lim]=mod;LL ret=0; 17 RG int i,l=max(0,sum-(st-1)*9 ),r=min( sum+1,(lim?bin[st]:10) ); 18 for(i=l;i<r;++i)ret+=dfs(st-1,sum-i,(cur*10+i)%mod,0); 19 if(lim && sum>=bin[st] ) 20 ret+=dfs(st-1,sum-bin[st],(cur*10+bin[st])%mod,1); 21 return f[st][sum][cur][lim]=ret; 22 } 23 inline LL calc(LL n) 24 { 25 RG int cnt=0;LL ret=0; 26 while(n)bin[++cnt]=n%10,n/=10; 27 memset(mark,0,sizeof(mark)); 28 for(mod=1;mod<=162;++mod)ret+=dfs(cnt,mod,0,1); 29 return ret; 30 } 31 int main() 32 { 33 RG int i,j;LL l,r; 34 scanf("%lld%lld",&l,&r); 35 printf("%lld\n",calc(r)-calc(l-1)); 36 }
這個和以前那個淘金很像……先預處理乘積,後面那個我一開始一直在想像上面1799的搞法帶着乘積走
而後發現不行,最後獲得了提示,對於每個乘積x,我去查詢l/x,r/x區間內乘積爲x的數就好了
這個轉化和以前數學上那個gcd很像:d|ij <==> d/gcd(i,d) | j
啊我好蠢啊
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdlib> 5 using namespace std; 6 #define RG register 7 #define LL long long 8 #define L 440000 9 #define UL 44000 10 int bin[20],len,cnt; 11 LL _9[20],mul[L],f[20][UL],l,r; 12 inline void dfs1(int st,int pre,LL multi) 13 { 14 mul[++cnt]=multi; 15 if(st==11)return; 16 for(RG int i=pre;i<10;++i) 17 if(multi*i<=r)dfs1(st+1,i,multi*i); 18 } 19 inline int id(LL val){return lower_bound(mul+1,mul+cnt+1,val)-mul;} 20 inline LL dfs(int st,int mul_id,bool limit) 21 { 22 if(mul[mul_id]>_9[st])return 0; 23 if(st==0)return 1; 24 RG int i,lim=(limit?bin[st]:10); 25 LL ret=0; 26 for(i=1;i<lim;++i) 27 if(mul[mul_id]%i==0) 28 ret+=f[st-1][id(mul[mul_id]/i)]; 29 if(lim&&bin[st]) 30 if(mul[mul_id]%bin[st]==0) 31 ret+=dfs(st-1,id(mul[mul_id]/bin[st]),1); 32 return ret; 33 } 34 inline LL query(int id,LL n) 35 { 36 LL ret=0;len=0; 37 while(n)bin[++len]=n%10,n/=10; 38 for(RG int i=1;i<len;++i)ret+=f[i][id]; 39 return ret+dfs(len,id,1); 40 } 41 inline LL calc(LL n) 42 { 43 if(!n)return 0;LL ret=0; 44 for(RG int i=1;mul[i]<=n&&i<=cnt;++i) 45 ret+=query(i,n/mul[i]); 46 return ret; 47 } 48 int main() 49 { 50 RG int i,j,k; 51 scanf("%lld%lld",&l,&r); 52 mul[++cnt]=1; 53 dfs1(0,2,1),sort(mul+1,mul+cnt+1), 54 cnt=unique(mul+1,mul+cnt+1)-mul-1; 55 for(_9[0]=i=1;i<=18;++i)_9[i]=_9[i-1]*9; 56 for(f[0][1]=1,i=1;i<=9;++i)f[1][i]=1; 57 for(i=2;i<=18;++i) 58 for(j=1;j<=cnt;++j)if(f[i-1][j]) 59 for(k=1;k<=9;++k)f[i][id(mul[j]*k)]+=f[i-1][j]; 60 printf("%lld\n", calc(r) - calc(l-1) ); 61 }
不知道怎麼混進來的AC自動機題目
前導0的處理須要注意,一開始沒有想好
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define L 1510 5 #define RG register 6 #define mod 1000000007 7 char s[L],str[L]; 8 bool ban[L]; 9 int n,cnt,ch[L][11],fail[L],q[L],hd,tl,plan[L][L]; 10 inline int dfs(int rt,int left) 11 { 12 if(ban[rt])return plan[rt][left]=0; 13 if(plan[rt][left])return plan[rt][left]; 14 int ret=0; 15 for(RG int i=0;i<10;++i) 16 if(!ban[ch[rt][i]]) 17 ret=(ret+dfs(ch[rt][i],left-1))%mod; 18 return plan[rt][left]=ret; 19 } 20 #define id(c) ((c)-'0') 21 signed main() 22 { 23 RG int i,j,m,rt,l,d,ans=0,good=1; 24 scanf("%s",s+1),n=strlen(s+1); 25 scanf("%d",&m); 26 cnt=1; 27 for(i=1;i<=m;++i) 28 { 29 scanf("%s",str+1),l=strlen(str+1); 30 for(rt=1,j=1;j<=l;++j) 31 { 32 d=str[j]-'0'; 33 if(!ch[rt][d])ch[rt][d]=++cnt; 34 rt=ch[rt][d]; 35 if(ban[rt])break; 36 } 37 ban[rt]=1; 38 } 39 for(hd=1,tl=0,i=0;i<10;++i) 40 if(ch[1][i])q[++tl]=ch[1][i],fail[ch[1][i]]=1; 41 else ch[1][i]=1; 42 while(hd<=tl) 43 for(rt=q[hd++],i=0;i<10;++i) 44 if(ch[rt][i])d=ch[rt][i],fail[d]=ch[fail[rt]][i],ban[d]|=ban[fail[d]],q[++tl]=d; 45 else ch[rt][i]=ch[fail[rt]][i]; 46 for(i=1;i<=cnt;++i)if(!ban[i])plan[i][0]=1; 47 for(i=1;i<=cnt;++i)if(!ban[i]) 48 for(j=1;j<n;++j)if(!plan[i][j])dfs(i,j); 49 for(i=1;i<n;++i)for(j=1;j<10;++j) 50 ans=(ans+plan[ch[1][j]][i-1])%mod; 51 for(rt=1,i=1;i<=n;++i) 52 { 53 for(d=s[i]-'0',j=(i==1?1:0);j<d;++j) 54 if(!ban[ch[rt][j]])ans=(ans+plan[ch[rt][j]][n-i])%mod; 55 rt=ch[rt][d]; 56 if(ban[rt]){good=0;break;} 57 } 58 printf("%d\n",ans+good); 59 }
題解在這裏面,綜合感不錯的題目……
至關於兩部分分開求和再除總數而後加權
第二部分求異或和很好想,統計每位0/1個數而後搞就行
關於第一部分………在%wq的思路以後打過去了
第一部分至關於對於每個數選一個數和它異或和最大
因爲選的那個數也要在n的範圍內,因此咱們不太好搞
這樣,咱們正難則反,先認爲每一個數的每一位都能貢獻上,再減去多餘的貢獻
因爲n的二進制第一位必定是1,因此在2^(len-1)到n-1這些數必定每一位都能貢獻上
那麼咱們一開始就拿着0~2^(len-1)-1這些數(len表明n的二進制長度),維護剩下多少數
從n的高位往低位考慮,若是n的某一位是1,那麼這一位若是填0的話,
如今這一位爲1的數(正好佔一半)就必定能貢獻後面全部位的值(即他們必定不會超限,因此後面能夠隨意填)
那麼咱們把它們扔掉,即更改剩下數的多少
這個和一開始分析的最高位的狀況相似
反之,若是爲0,那麼這一位爲0的全部數(也是佔一半)因爲不能填1而沒法貢獻這一位的異或值
那麼咱們在答案中減去對應的值
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 #define RG register 6 #define LL long long 7 #define db double 8 LL bin[64]; 9 int bit[64],len; 10 int main() 11 { 12 RG int i;LL n,m,tmp,cnt0,cnt1; 13 db val1=0,val2=0,p,q; 14 for(bin[0]=i=1;i<=62;++i)bin[i]=bin[i-1]<<1; 15 scanf("%lld%lf",&n,&p),m=n-1; 16 tmp=m;while(tmp)bit[++len]=tmp&1,tmp>>=1; 17 for(i=len;~i;--i) 18 { 19 tmp=n>>(i+1),cnt0=cnt1=tmp*bin[i]; 20 if(n&bin[i])cnt0+=bin[i],cnt1+=(bin[i]-1)&n; 21 else cnt0+=(bin[i]-1)&n; 22 val2+=2.0*cnt0*cnt1*bin[i]; 23 } 24 val2/=n*1.0*n; 25 val1=n*1.0*(bin[len]-1);tmp=bin[len]; 26 for(i=len;i;--i) 27 if(bit[i])tmp>>=1; 28 else val1-=(tmp>>1)*1.0*bin[i-1]; 29 printf("%.10lf\n",p*val1/n+(1-p)*val2 ); 30 }
感受是上面一題的增強版
本身想的是dfs打法,可是因爲狀況太多沒法手動分類討論,打不出來
數組定義定義f[i][2][2][2],後面三個0/1分別表明是否知足i<=n,j<=m,i^j>=k
如今我發現的AC寫法(茴香豆的茴有四種寫法你知道嘛)
1.(大部分網上題解使用的)4維數組dp
發現網上大部分人是用的迭代dp的打法
和我定義是同樣的,但是……
代碼實現出人意料的簡潔
dp寫法和dfs寫法的確是各有所長
dp適合用不少for循環和邊界特判無腦處理掉大量的分類討論
而dfs適合沒法很好用for循環枚舉的東西
Ps:dp寫法有一個地方不是太懂,就是爲何最後要把數組的每一個元素都計算一遍
咱們須要的答案難道不就是ans[1][1][1]嗎
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 #define RG register 6 #define LL long long 7 LL n,m,k,bin[64],f_ge[64][2][2][2],f_sum[64][2][2][2]; 8 int main() 9 { 10 RG int mod,i,ta,tb,tc,a,b,c,x,y,z,t,len,lena,lenb,lenc,bita,bitb,bitc; 11 LL ans,tmp;scanf("%d",&t); 12 while(t--) 13 { 14 scanf("%lld%lld%lld%d",&n,&m,&k,&mod),--n,--m; 15 lena=lenb=lenc=0; 16 tmp=n;while(tmp)++lena,tmp>>=1; 17 tmp=m;while(tmp)++lenb,tmp>>=1; 18 tmp=k;while(tmp)++lenc,tmp>>=1; 19 len=max(lena,max(lenb,lenc)); 20 for(bin[0]=i=1;i<=len;++i)bin[i]=(bin[i-1]<<1)%mod; 21 memset(f_ge,0,sizeof(f_ge)),memset(f_sum,0,sizeof(f_sum)); 22 f_ge[len+1][1][1][1]=1;ans=0; 23 for(i=len;~i;--i) 24 { 25 bita=(n>>i)&1,bitb=(m>>i)&1,bitc=(k>>i)&1; 26 for(a=0;a<2;++a)for(b=0;b<2;++b)for(c=0;c<2;++c) 27 if(f_ge[i+1][a][b][c]) 28 for(x=0;x<2;++x) 29 { 30 if(a && x>bita)break; 31 for(y=0;y<2;++y) 32 { 33 if(b && y>bitb)break; 34 z=x^y; 35 if(c && z<bitc)continue; 36 ta=(a && bita==x)?1:0,tb=(b && bitb==y)?1:0,tc=(c && bitc==z)?1:0; 37 f_ge[i][ta][tb][tc]=(f_ge[i][ta][tb][tc]+f_ge[i+1][a][b][c])%mod; 38 f_sum[i][ta][tb][tc]=( f_sum[i][ta][tb][tc]+f_sum[i+1][a][b][c])%mod; 39 if(z)f_sum[i][ta][tb][tc]=( f_sum[i][ta][tb][tc]+ bin[i]*f_ge[i+1][a][b][c]%mod )%mod; 40 } 41 } 42 } 43 k%=mod; 44 for(a=0;a<2;++a)for(b=0;b<2;++b)for(c=0;c<2;++c) 45 ans=(ans+f_sum[0][a][b][c]-k*f_ge[0][a][b][c]%mod+mod)%mod; 46 printf("%lld\n",ans); 47 } 48 }
啊……我要再研究一下dfs寫法,看看能不能打出來
upd:我完蛋了,我打不出來2333
2.wq式dp打法,強大又快速,wq Orzzzzzzzzzzzzzzzzzzzzzzzz
很巧妙,刷新了我對數位Dp的認識,讓我理解更加深刻了
讓wq講了一個多小時,感受本身智商掉沒了2333
可是仍是不太懂,沒法用語言描述……
等我更強了再來補這個作法……
思路大概是很清真的,總的來講就是預處理前i位數的子串和,以及前綴子串之和,而後按照數位DP那樣限制轉移
可是……那個轉移的式子……
啊真是讓人痛苦,那個式子我總共大改了5遍纔打過,而且有不少一開始沒有注意到的細節
之後作題必需要先想好式子
每一項是什麼爲何都要想清楚
要不特別耽誤時間……有的時候船到橋頭……就翻船了……
感受思惟嚴謹性獲得了提升2333
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define RG register 5 #define mod 20130427 6 #define N 100010 7 #define LL long long 8 char cB[1<<15],*S=cB,*T=cB; 9 #define getc (S==T&&(T=(S=cB)+fread(cB,1,1<<15,stdin),S==T)?0:*S++) 10 inline int read() 11 { 12 RG int x=0;RG char c=getc; 13 while(c<'0'|c>'9')c=getc; 14 while(c>='0'&c<='9')x=10*x+(c^48),c=getc; 15 return x; 16 } 17 inline int Sum(int a){return ((LL)a*(a+1ll)/2)%mod;} 18 inline int max(int a,int b){return a>b?a:b;} 19 inline int min(int a,int b){return a<b?a:b;} 20 int ge2[N],sum2[N],ge3[N],sum3[N],no_zero_sum3[N],B,lena,bit[N],lenb,bin[N]; 21 inline int calc(bool start,int left,int lim,int cnt,int sum,int sum_of_substring ) 22 { 23 if(lim==0)return 0; 24 if(start) 25 return 26 ( 27 (LL) Sum(lim-1) * ge2[left] %mod * bin[left] %mod + //前與後鏈接以後前面的貢獻 28 (LL) ( lim - 1 ) %mod * sum3[left] %mod + no_zero_sum3[left] %mod +//後面的子串 29 (LL) ( lim - 1 ) %mod * sum2[left] %mod//前與後鏈接以後後面的貢獻 30 )%mod; 31 int new_sum=( (LL) sum * B %mod * lim %mod + (LL) Sum(lim-1) * cnt %mod ) %mod; 32 return 33 ( 34 (LL) sum_of_substring * lim %mod * bin[left] %mod + //以前的子串 35 (LL) new_sum * ge2[left] %mod * bin[left] %mod + //前與後鏈接以後前面的貢獻 36 (LL) lim %mod * sum3[left] %mod +//後面的子串 不乘cnt 37 (LL) cnt * lim %mod * sum2[left] %mod//前與後鏈接以後後面的貢獻 ,要乘cnt 由於再前面不一樣 38 )%mod; 39 } 40 inline int dfs(bool start,int st,int cnt,int sum,int sum_of_substring) 41 { 42 if(st==0)return 0; 43 int new_sum=( (LL) sum * B %mod + (LL) ( cnt + 1 ) * bit[st] %mod )%mod; 44 return 45 ( new_sum + calc(start, st-1 , bit[st] , cnt + 1 , sum , sum_of_substring ) + 46 dfs(0, st - 1 , cnt + 1, new_sum , (sum_of_substring + new_sum)%mod ) )%mod; 47 } 48 signed main() 49 { 50 RG int i,j,len,ans; 51 B=read(),lena=read(); 52 for(i=lena;i;--i)bit[i]=read(); 53 lenb=read();len=max(lena,lenb); 54 if(lena>1||bit[1]>0) 55 { 56 --bit[1],j=1; 57 while(bit[j]<0)bit[j]+=B,--bit[j+1],++j; 58 while(lena>1&&!bit[lena])--lena; 59 } 60 for(bin[0]=ge2[0]=i=1;i<=len;++i) 61 { 62 bin[i]=(LL)bin[i-1]*B%mod; 63 ge2[i]=( ge2[i-1] + bin[i] )%mod; 64 ge3[i]=(LL) Sum(i) * bin[i] %mod; 65 sum2[i]=( (LL) sum2[i-1] * B %mod + Sum ( bin[i] - 1 ) )%mod; 66 sum3[i]=( (LL) Sum(B-1) * bin[i-1] %mod * ge2[i-1] %mod + (LL)B * sum2[i-1] %mod + (LL) B * sum3[i-1] %mod )%mod; 67 no_zero_sum3[i]=( (LL) Sum(B-1) * bin[i-1] %mod * ge2[i-1] %mod + 68 (LL) (B - 1) * sum2[i-1] %mod + (LL) (B - 1) * sum3[i-1] %mod + no_zero_sum3[i-1] )%mod; 69 } 70 ans=mod-dfs(1,lena,0,0,0); 71 for(i=lenb;i;--i)bit[i]=read(); 72 printf("%d\n",(ans+dfs(1,lenb,0,0,0))%mod); 73 }
其實還有另一種思路,那就是反過來從前日後走,而且用矩陣乘優化
這個是wq的原創思路……
沒作呢,據說挺簡單,可是我沒想出來
此次時間不夠了……不想慫題解
有時間再作……
此次作的題就是這麼多……接下來要去找「有思惟難度的DP題」了……加油咯……