妈蛋真是脑洞大开!
看看这个交错和问题:
各种溢出和逻辑上错误导致的越界、对象错误防不胜防。
给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数:
f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1
例如:
f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4
给定
输入数据仅一行包含三个整数,l, r, k(0 ≤ l ≤ r ≤ 1018, |k| ≤ 100)。
输出一行一个整数表示结果,考虑到答案可能很大,输出结果模 109 + 7。
对于样例 ,满足条件的数有 110 和 121,所以结果是 231 = 110 + 121。
更多样例:
Input |
4344 3214567 3 |
Output |
611668829 |
Input |
404491953 1587197241 1 |
Output |
323937411 |
Input |
60296763086567224 193422344885593844 10 |
Output |
608746132 |
Input |
100 121 -1 |
Output |
120 |
100 121 0
231
状态:
[i][j][k]
边界:
#include <iostream> #include <vector> #include <assert.h> #include <math.h> using namespace std; typedef long long int ll; typedef pair<ll,ll> Pair;//@pair<int,ll> can overflow!!! should be pair<ll,ll> #define MOD 1000000007 int dump(ll x,int a[]){ int i=0;while(x>0){ a[i++]=x%10;x/=10; } if(i==0) a[0]=0,i=1; return i; } ll dp(ll x, int K){ // return the count of number in [0~x) that f(number)=K if(x==0) return 0; int a[18];int len=dump(x,a); int minN=0-(len/2)*9,maxN=(len+1)/2*9;//0909.. 9090.. if(K<minN||K>maxN) return 0; int delta=0-minN,n=maxN-minN+1; ////p[i][j][k] : delta+ (+/-)xi .... -x1 + x0 = k, xi = j vector<vector<vector<Pair> > > p(len,vector<vector<Pair> >(10, vector<Pair>(n,Pair(0,0)))); //init for(int j=0;j<10;j++) p[0][j][j+delta]=Pair(1,j); ////i=0. j=x0, x0+delta=k for(int i=0;i<len-1;i++){ vector<Pair> cnt(n,Pair(0,0)); for(int j=0;j<10;j++){ for(int k=0;k<n;k++){ Pair &s=p[i][j][k]; cnt[k].first=(s.first+cnt[k].first)%MOD; cnt[k].second=(s.second+cnt[k].second)%MOD; } } // [i][k] => [i+1][j][k+(+/-)j] for(int j=0;j<10;j++){ int fh=pow(-1,i+1); ll d=(ll)pow(10,i+1)%MOD*j%MOD;//@error:pow(10,i+1)*j can overflow for(int k=0;k<n;k++){ if(k+fh*j<0||k+fh*j>=n) continue;//@attention: here k+fh*j can be unavailable Pair &s=p[i+1][j][k+fh*j]; s.first=cnt[k].first; assert(d<MOD); assert(s.first<MOD); s.second=(d*s.first%MOD+cnt[k].second)%MOD; } } } // count of number in [0~xm..x3x2x1x0] , where m<len-1 ll num=0; //int b[len]; for(int i=len-2;i>=0;i--){ //b[i+1]=0; int j; int fh=pow(-1,i); if(i==0) j=0; else j=1; //// if(fh==1) (k-delta)=K; else -(k-delta)=K int k=fh*K+delta; if(!(k>=0&&k<n)) continue;//here k can be unavailable // assert(k>=0&&k<n);//@error: logic error, here k can be out of [0,n) for(;j<10;j++){ //b[i]=j; num=(num+p[i][j][k].second)%MOD; } } //count of number in [10000...00,x) ll s=0; int lst=0; int fh=pow(-1,len-1); for(int i=len-1;i>=0;i--){ int j; if(i==len-1) j=1; else j=0; int k=(K-lst)*fh+delta; // assert(k>=0&&k<n);//@error: logic error, here k can be out of [0,n) if(!(k>=0&&k<n)) ;//@attention: k can be unavailable else for(;j<a[i];j++){ //// lst+fh*(k-delta)=K, k=(K-lst)/fh+delta Pair &q=p[i][j][k]; ll d=(q.second+s*q.first%MOD)%MOD; num=(num+d)%MOD; } lst+=pow(-1,i)*fh*a[i]; // s+=pow(10,i)*a[i]; //@error: here s will overflow!!!! s=(s+(ll)pow(10,i)*a[i]%MOD)%MOD; //@attention: (ll) has higher priority than * //@attention: pow(10,i)*a[i] will not overflow } return num; } int main(){ ll l,r;int k; ////debug // for(r=999999;r<999999999;r+=10000){ // for(k=1;k<100;k++){ // cout<<dp(r,k)<<endl; // } // } cin>>l>>r>>k; ll x1=dp(l,k); ll x2=dp(r,k); ll cnt=(x2-x1)%MOD; int b[18];int len=dump(r,b); int fh=pow(-1,len-1);int kk=0; for(int i=len-1;i>=0;i--) kk+=fh*pow(-1,i)*b[i]; // if(kk==k) cnt++;//@error: logic error: cnt++ should be cnt+=r if(kk==k) cnt=(cnt+r%MOD)%MOD; cout<<(cnt+MOD)%MOD<<endl; return 0; }
或者:
#include <cstdio> #include <iostream> using namespace std; typedef long long LL; const LL Mod=1000000007; int k0; LL cnt[20][20*9], sum[20][20*9]; void dp(int n) { int sign=-1; cnt[0][k0]=1; sum[0][k0]=0; for (int i=0; i<n; ++i) { sign=-sign; for (int j=-i/2*9; j<=(i+1)/2*9; ++j) for (int l=0; l<=9; ++l) { int x=j+sign*l+k0; cnt[i+1][x]=(cnt[i+1][x]+cnt[i][j+k0])%Mod; sum[i+1][x]=(sum[i+1][x]+sum[i][j+k0]*10+cnt[i][j+k0]*l)%Mod; } } } LL calc(int n, int k) { if (n<=0) return 0; LL res=calc(n-1, k); LL base=1; for (int i=1; i<n; ++i) base*=10; for (int i=1; i<=9; ++i) res=(res+i*base%Mod*cnt[n-1][i-k+k0]+sum[n-1][i-k+k0])%Mod; return res; } LL work(LL num, int k) { int n=0, a[20]; LL base=1; for (LL x=num; x; x/=10) a[n++]=x%10, base*=10; int sign=-1, k1=k; LL res=calc(n-1, k), pre=0; for (int i=n-1; i>=0; --i) { base/=10; sign=-sign; pre*=10; for (int j=(i==n-1? 1:0); j<a[i]; ++j) { int suc=(k1-j*sign)*(-sign)+k0; res=(res+(pre+j)*base%Mod*cnt[i][suc]+sum[i][suc])%Mod; } pre+=a[i]; k1-=a[i]*sign; } if (k1==0) res=(res+pre)%Mod; return res; } int main() { LL l, r; int k; cin>>l>>r>>k; int n=0; for (LL x=r; x; x/=10) ++n; k0=n/2*9; dp(n); cout<<((work(r, k)-work(l-1, k))%Mod+Mod)%Mod<<endl; return 0; }
另一种写法
//#pragma comment(linker,"/STACK:102400000,102400000") template<class T> inline T sqr(T x) { return x * x; } typedef long long LL; typedef unsigned long long ULL; typedef long double LD; typedef pair<int, int> PII; typedef pair<PII, int> PIII; typedef pair<LL, LL> PLL; typedef pair<LL, int> PLI; typedef pair<LD, LD> PDD; #define MP make_pair #define PB push_back #define sz(x) ((int)(x).size()) #define clr(ar,val) memset(ar, val, sizeof(ar)) #define istr stringstream #define FOR(i,n) for(int i=0;i<(n);++i) #define forIt(mp,it) for(__typeof(mp.begin()) it = mp.begin();it!=mp.end();it++) const double PI = acos(-1.0); #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define lowbit(u) (u&(-u)) using namespace std; #define MOD 1000000007 PLL dp[25][205][2][2]; int digit[25]; LL l,r,k,p10[25]; PLL dfs(int cur,int sum,int x,int lead,int limit){ if(cur<0){ if(sum==k) return MP(0,1); return MP(0,0); } if(!limit&&~dp[cur][sum][x][lead].first) return dp[cur][sum][x][lead]; if(!lead) x = 1; LL ans = 0,cnt = 0; int ed = limit?digit[cur]:9; int p = 1; if(x==0) p = -1; for(int i = 0;i<=ed;i++){ PLL ret = dfs(cur-1,sum+i*p,!x,lead||i,limit&&i==ed); ans+=i*p10[cur]%MOD*ret.second%MOD+ret.first; ans%=MOD; cnt+=ret.second; cnt%=MOD; } if(!limit) dp[cur][sum][x][lead] = MP(ans,cnt); return MP(ans,cnt); } PLL solve(LL n){ if(n<0) return MP(0,0); int cnt = 0; while(n){ digit[cnt++] = n%10; n/=10; } return dfs(cnt-1,100,1,0,1); } int main(void){ #ifndef ONLINE_JUDGE //freopen("/Users/mac/Desktop/data.in","r",stdin); #endif p10[0] = 1; for(int i = 1;i<=20;i++) p10[i] = 1ll*p10[i-1]*10%MOD; memset(dp,-1,sizeof(dp)); scanf("%lld %lld %lld",&l,&r,&k); k+=100; LL ret = solve(r).first-solve(l-1).first; if(ret<0) ret+=MOD; printf("%lld\n",ret); return 0; }
#pragma comment(linker, "/STACK:36777216") #include <map> #include <set> #include <cmath> #include <ctime> #include <queue> #include <stack> #include <cstdio> #include <string> #include <vector> #include <iomanip> #include <cassert> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define lc(x) (x << 1) #define rc(x) (lc(x) + 1) #define lowbit(x) (x & (-x)) #define PI (acos(-1)) #define lowbit(x) (x & (-x)) #define EPS 1e-10 #define MAXN 100005 #define MAXM 2005 #define LL long long #define DB double #define ULL unsigned long long #define PII pair<int, int> #define INF 0x3fffffff #define PB push_back #define MP make_pair #define MOD 1000000007 using namespace std; LL f[20][405][2][2], f2[20][405][2][2], ten[20], dig[20]; LL Mul(LL a, LL b){ a %= MOD, b %= MOD; return (a * b) % MOD; } int K; LL dp(int pos, int sum, bool first, bool ud, bool flag){ if(sum < 0 || sum > 400) return 0; if(pos == -1) return (sum == (200 + K)); if(!flag && f[pos][sum][first][ud] != -1) return f[pos][sum][first][ud]; LL res = 0; for(int i = 0, l = flag ? dig[pos] : 9; i <= l; i ++){ if(first == true){ if(i == 0) res += dp(pos - 1, sum, 1, 0, flag && i == l); else res += dp(pos - 1, sum + i, 0, 1, flag && i == l); } else{ int tmp; if(ud == 0) tmp = sum + i; else tmp = sum - i; res += dp(pos - 1, tmp, 0, !ud, flag && i == l); } res %= MOD; } return flag ? res : f[pos][sum][first][ud] = res; } LL dp2(int pos, int sum, bool first, bool ud, bool flag){ if(sum < 0 || sum > 400) return 0; if(pos == -1) return 0; if(!flag && f2[pos][sum][first][ud] != -1) return f2[pos][sum][first][ud]; LL res = 0; for(int i = 0, l = flag ? dig[pos] : 9; i <= l; i ++){ LL has = 0; if(first == true){ if(i == 0) has = dp(pos - 1, sum, 1, 0, flag && i == l), res += dp2(pos - 1, sum, 1, 0, flag && i == l); else has = dp(pos - 1, sum + i, 0, 1, flag && i == l), res += dp2(pos - 1, sum + i, 0, 1, flag && i == l); } else{ int tmp; if(ud == 0) tmp = sum + i; else tmp = sum - i; has = dp(pos - 1, tmp, 0, !ud, flag && i == l); res += dp2(pos - 1, tmp, 0, !ud, flag && i == l); } res %= MOD; LL tmp; tmp = (LL) i * ten[pos] % MOD; tmp = (tmp * has) % MOD; res = (res + tmp) % MOD; //res += Mul(Mul((LL) i, ten[pos]), has); res %= MOD; } return flag ? res : f2[pos][sum][first][ud] = res; } LL calc(LL x){ if(x < 0) return 0; int cnt = 0; while(x) dig[cnt ++] = x % 10, x /= 10; return dp2(cnt - 1, 200, 1, 0, 1) % MOD; } int t; LL l, r; int main(){ //freopen("in.txt", "r", stdin); ten[0] = 1; for(int i = 1; i < 20; i ++) ten[i] = (ten[i - 1] * 10) % MOD; while(cin >> l >> r >> K){ memset(f, -1, sizeof(f)); memset(f2, -1, sizeof(f2)); LL k2 = calc(r), k1 = calc(l - 1); LL ans = (k2 - k1 + MOD) % MOD; cout << ans << endl; //printf("%lld\n", ans); } }
/* * temp.cpp * * Created on: 2012-7-18 * Author: BSBandme */ //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <fstream> #include <string.h> #include <cstdio> #include <algorithm> #include <string> #include <vector> #include <queue> #include <cassert> #include <list> #include <iomanip> #include <math.h> #include <deque> #include <utility> #include <map> #include <set> #include <bitset> #include <numeric> #include <climits> #include <cctype> #include <cmath> #include <cstdlib> #include <ctime> #include <functional> #include <sstream> #include <tr1/unordered_set> #include <tr1/unordered_map> using namespace std; using namespace tr1; #define mpr make_pair typedef unsigned int ui; typedef unsigned long long ull; typedef long long ll; typedef pair <int, int> pii; typedef pair <ll, ll> pll; typedef pair <double, double> pdd; typedef vector <int> vi; typedef vector <ll> vll; typedef vector <double> vd; typedef vector <string> vs; typedef map <string, int> mpsi; typedef map <double, int> mpdi; typedef map <int, int> mpii; const double pi = acos(0.0) * 2.0; const double eps = 1e-12; const int step[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; template <class T> inline T abs1(T a) {return a < 0 ? -a : a;} template <class T> inline T max1(T a, T b) { return a > b ? a : b; } template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); } template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); } template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); } template <class T> inline T min1(T a, T b) { return a < b ? a : b; } template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); } template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); } template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); } inline int jud(double a, double b){ if(abs(a) < eps && abs(b) < eps) return 0; else if(abs1(a - b) / abs1(a) < eps) return 0; if(a < b) return -1; return 1; } template <typename t> inline int jud(t a, t b){ if(a < b) return -1; if(a == b) return 0; return 1; } // f_lb == 1代表返回相同的一串的左边界,f_small == 1代表返回如果没有寻找的值返回小的数 template <typename it, typename t1> inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){ int be = 0, en = na - 1; if(*a <= *(a + na - 1)){ if(f_lb == 0) while(be < en){ int mid = (be + en + 1) / 2; if(jud(*(a + mid), val) != 1) be = mid; else en = mid - 1; }else while(be < en){ int mid = (be + en) / 2; if(jud(*(a + mid), val) != -1) en = mid; else be = mid + 1; } if(f_small && jud(*(a + be), val) == 1) be--; if(!f_small && jud(*(a + be), val) == -1) be++; } else { if(f_lb) while(be < en){ int mid = (be + en + 1) / 2; if(jud(*(a + mid), val) != -1) be = mid; else en = mid - 1; }else while(be < en){ int mid = (be + en) / 2; if(jud(*(a + mid), val) != 1) en = mid; else be = mid + 1; } if(!f_small && jud(*(a + be), val) == -1) be--; if(f_small && jud(*(a + be), val) == 1) be++; } return be; } template <class T> inline T lowb(T num) {return num & (-num); } inline int bitnum(ui nValue) { return __builtin_popcount(nValue); } inline int bitnum(int nValue) { return __builtin_popcount(nValue); } inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); } inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); } inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); } inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); } inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); } inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); } long long pow(long long n, long long m, long long mod = 0){ if(m < 0) return 0; long long ans = 1; long long k = n; while(m){ if(m & 1) { ans *= k; if(mod) ans %= mod; } k *= k; if(mod) k %= mod; m >>= 1; } return ans; } #define MOD 1000000007 template <class t1, class t2> inline void add(t1 &a, t2 b, int mod = -1) { if(mod == -1) mod = MOD; a += b; while(a >= mod) a -= mod; while(a < 0) a += mod; } //#define debug //.........................mi.......feng......xian.......xia.......jin.......zhi.......hack...............................................