参考链接(参考代码是正确的)
这里对X进制的理解就是:321(对应的进制分别为8、10、2)--高位3是由2个十进制的数(即中间的数)进3次位+1个二进制位进2次位得来的,而中间的数是由低位进2次位得来的 321=3*10*2+2*2+1
/*结果WA,不知道为什么*/
#include<bits/stdc++.h>
using namespace std;
int n,ma,mb;
long long a[100005],b[100005];
const int modd=1e9+7 ;//注意下写法
int main()
{
cin>>n;
cin>>ma;
for(int i=ma;i>=1;i--) cin>>a[i];//低位在前
cin>>mb;
for(int i=mb;i>=1;i--) cin>>b[i];
long long w[100005];//w[]存每位对应的进制
long long mul[100005];//mul[]存每位进制的前缀积
//w[0]=1;
mul[1]=1;
for(int i=max(ma,mb);i>=1;i--){
w[i]=max((long long)2,max(a[i],b[i])+1);
}
for(int i=2;i<=max(ma,mb);i++){
mul[i]=(mul[i-1]*w[i-1])%modd;
}
long long A,B;
for(int i=ma;i>=1;i--){
A=(A+a[i]*mul[i])%modd;
}
for(int i=mb;i>=1;i--){
B=(B+b[i]*mul[i])%modd;
}
cout<<(A-B+modd)%modd<<endl;//注意下写法
}
只是使用二维前缀和过80%
/*二维前缀和*/
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long k,s[505][505],res;
int a[505][505];
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) cin>>a[i][j];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) {
s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i][j];
}
}
for(int x1=1;x1<=n;x1++){
for(int x2=x1;x2<=n;x2++){
for(int y1=1;y1<=m;y1++){
for(int y2=y1;y2<=m;y2++){
if(x2>=x1&&y2>=y1){
if(s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]<=k){
res++;
}
}
}
}
}
}
cout<<res;
}
/*二维前缀和+双指针*/
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long k,s[505][505],res;
int a[505][505];
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) cin>>a[i][j];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) {
s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i][j];
}
}
res=0;
for(int x1=1;x1<=n;x1++){
for(int x2=x1;x2<=n;x2++){
for(int y1=1,y2=y1;y2<=m;y2++){
while(s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]>k){
y1++;
}
res+=(y2-y1+1);
}
}
}
cout<<res;
}
参考链接(这个参考有两个点MLE)
/*没太懂,答案输出不对*/
#include<bits/stdc++.h>
using namespace std;
const int m=1e9+7;
int n;
long long f[10000005][2];
int main()
{
cin>>n;
f[0][0]=1;
for(int i=1;i<=n;i++){
f[i][0]=(f[i-1][1]+f[i-1][2]+f[i-1][0])%m;//在第1、2列,所以把+f[i-2][0]直接去掉即可
if(i>=2){
f[i][0]=(f[i-2][0]+f[i][0])%m;
f[i][1]=(f[i-2][0]+f[i-1][2])%m;
f[i][2]=(f[i-2][0]+f[i-1][1])%m;
}
}
cout<<f[n][0]%m;
}
另一种思路,仍然是两个点MLE
/*为什么用DP:排i列是是由前面的状态推出来的*/
#include<bits/stdc++.h>
using namespace std;
const int modd=1e9+7;
int n;
long long f[10000005][2];
//f[i][0]表示排第i列(即要给第i列排满时)第i列上没有积木,则f[i][1]表示有一个积木
int main(){
cin>>n;
//memset(f,0,sizeof(f));使用memset MLE,不使用有两个点MLE
f[1][0]=1;f[1][1]=2; //假设0列存在
f[2][0]=2;f[2][1]=4;
//f[3][0]=2;f[3][1]=3;
if(n==1) cout<<1;
else if(n==2) cout<<2;
else{
for(int i=3;i<=n;i++){
f[i][0]=(f[i-1][0]+f[i-2][0]+f[i-2][1])%modd;
f[i][1]=(f[i-1][0]*2+f[i-1][1])%modd;
}
cout<<f[n][0]%modd;
}
}
砍竹子参考链接