本来是想去学数位DP,作死挑了这道题,爆炸。。。
听说正确姿势应该是去做bzoj4521【手机】,听说迪克们当场都A了,Orz
然后对于4513,我只想说,一、脸、懵、逼
首先,我是无论如何都无法想到f[i][x][y][z]精妙的表示方式的
……讲不下去了,搬来罗爷爷的blog救场http://yyhslyz.is-programmer.com/posts/199294.html
好吧我承认这道题我完全没理解。。。。
代码可以看lych的blog.
不过其中又get了一个bug,原来<的优先级大于^,2333
-----------------------------------------------
首先,数位dp是啥.
它一般与二进制,异或有关,有些比较容易看出来,有些并不.
解决问题的核心思想就是逐位确定.
我还是想再说一遍,感觉自己做dp题还是没有任何的长进,可能弱菜看过的题太少.
#include<cstdio> #include<algorithm> #include<cstring> #define N 105 #define ad add #define ll long long using namespace std; ll n,m,k,T; ll p,lenm,lenn,lenk,tmp,len,a[N],b[N],c[N],f[N][][][],g[N][][][],bin[N]; void add(ll &x,ll y) { x+=y;if(x>=p)x-=p; } ll max(ll a,ll b) { if(a>b) return a;else return b; } int main() { scanf("%d",&T); while(T--) { scanf("%lld%lld%lld%lld",&m,&n,&k,&p); memset(a,,,,sizeof(c)); lenm=;)a[++lenm]=m&; lenn=;)b[++lenn]=n&; lenk=;)c[++lenk]=k&; len=max(max(lenm,lenn),lenk); bin[]=;;i<=len;i++)bin[i]=(bin[i-]<<)%p; memset(f,,,sizeof(g)); ; x<; x++) ; y<; y++) ; z<; z++) ; u<((x)?:a[]); u++) ; v<((y)?:b[]); v++) ] || z){ ad(f[][x][y][z],((u^v)-c[]+p)%p); ad(g[][x][y][z],); } ; i<=len; i++) ; x<; x++) ; y<; y++) ; z<; z++) ; u<=max(x,a[i]); u++) ; v<=max(y,b[i]); v++) if ((u^v)>=c[i] || z){ int j=x|(u<a[i]),k=y|(v<b[i]),l=z|((u^v)>c[i]); tmp=(ll)g[i-][j][k][l]*((u^v)-c[i])*bin[i-]%p; ) tmp+=p; ad(tmp,f[i-][j][k][l]); ad(f[i][x][y][z],tmp); ad(g[i][x][y][z],g[i-][j][k][l]); } printf(][][]); } }
2016/06/01
[bzoj4521]
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define mo 998244353 using namespace std; ll x,y,n,dp[][][][][][][]; ]; ll solve(ll x) { n=;int p,q,r; while(x) { a[++n]=x%;x/=; } ); ;i<=n/;i++)swap(a[i],a[n-i+]); memset(dp,,sizeof(dp)); ;i<a[];i++) ;j<=;j++){ ||j==)p=;; ||j==)q=;; dp[][i][j][p][q][][]=; } ;j<a[];j++){ ]==||j==)p=;; ]==||j==)q=;; dp[][a[]][j][p][q][][]=; } ]==||a[]==)p=;; ]==||a[]==)q=;; dp[][a[]][a[]][p][q][][]=; ;i<n;i++) ;j<=;j++) ;k<=;k++) ;I<=;I++) ;J<=;J++) ;K<=;K++) ;l<=;l++){ )p=;else p=I; )q=;else q=J; ;else r=K; dp[i+][k][l][p][q][r][]+=dp[i][j][k][I][J][K][]; ])dp[i+][k][l][p][q][r][]+=dp[i][j][k][I][J][K][]; ])dp[i+][k][l][p][q][r][]+=dp[i][j][k][I][J][K][]; } ll ans=; ;i<=;i++) ;j<=;j++) ;k<=;k++) ans+=dp[n][i][j][][][][k]+dp[n][i][j][][][][k]+dp[n][i][j][][][][k]; return ans; } int main() { scanf("%lld%lld",&x,&y); printf()); }