題目大意:求指定範圍內與7不沾邊的所有數的平方和。結果要mod 10^9+7(鬼畜の元凶)
解題思路:
與7不沾邊的數需要滿足三個條件。
①不出現7
②各位數和不是7的倍數
③這個數不是7的倍數
這三個條件都是基礎的數字dp。
但是這題要統計的不是符合條件個數,而是平方和。
也就是說在dp時候,要重建每個數,算出平方,然後求和。
需要維護三個值(推薦使用結構體), 假定dfs推出返回的結構體是next,當前結果的結構體是ans
①符合條件數的個數 cnt
②符合條件數的和 sum
③符合新增數的平方和 sqsum
其中①是基礎數字dp。②next.sum+(10^len*i)*ans.cnt,其中(10^len*i)*ans.cnt代表以len為首位的這部分數字和。
③首先重建一下這個數,(10^len*i+x),其中x是這個數的後面部分,則平方和就是(10^len*i)^2+x^2+2*10^len*i*x,其中x^2=next.sqsum
整體還要乘以next.cnt,畢竟不止乙個。
這樣sqsum+=next.sqsum
sqsum+=(2*10^len*i*x)*next.cnt=(2*10^len*i)*next.sum(神奇的化簡)
sqsum+=(10^len*i)^2*next.cnt
然後就是本題鬼畜的地方了,cnt,sum,sqsum,三個都是達到了int64極限。
也即是說凡是這三個值參與運算的地方,都要狠狠打上mod,尤其是cnt!一坨坨mod出現了。
mod之後統計函式也有個小陷阱,那就是f(r)在mod之後有可能小於f(l-1)。也就是要對負數取正數模。
負數取模的方法(ans%mod+mod)%mod。
#include "cstdio
"#include
"math.h
"#include
"cstring
"#define mod 1000000007ll
#define ll long long
struct
status
status(ll cnt,ll sum,ll sqsum):cnt(cnt),sum(sum),sqsum(sqsum) {}
}dp[
20][10][10
];ll digit[
20],p[25
];status dfs(
int len,int re1,int re2,bool
fp)
if(!fp) dp[len][re1][re2]=ans;
return
ans;
}ll f(ll x)
status tt=dfs(len,0,0,true
);
return
tt.sqsum;
}int
main()
}
11814266
2014-10-07 00:19:33
accepted
4507
15ms
276k
1527 b
c++physcal
HDU 4507 恨7不成妻
problem description 單身 依然單身!吉哥依然單身!ds級碼農吉哥依然單身!所以,他生平最恨情人節,不管是214還是77,他都討厭!吉哥觀察了214和77這兩個數,發現 2 1 4 7 7 7 7 2 77 7 11 最終,他發現原來這一切歸根到底都是因為和7有關!所以,他現在甚至...
HDU 4507 恨7不成妻(數字dp )
題目 求在一定區間內和7無關的數字的平方和。如果乙個整數符合下面3個條件之一,那麼我們就說這個整數和7有關 1 整數中某一位是7 2 整數的每一位加起來的和是7的整數倍 3 這個整數是7的整數倍 基本思想是 x y 2 x 2 2 x y y 2 維護sum和sqrt sum,以及數量cnt來確定用...
HDU4507 恨7不成妻(數字dp)
給定區間 l r 1 leq l r leq 1e18 求在區間中滿足下列條件的所有數x的平方和 不存在數字7 不是7的倍數 每一位的數字的和也不是7的倍數 數字dp 狀態 位置i,數對7取模j,各個位的和對7取模 是否頂上界 下面的 用記憶化搜尋方式實現,從低位向高位遞進。已知後面i位數滿足的平方...