前言
你有没有试过以下几种情况:
- 代码在别的OJ上能过,在洛谷上就T了
- 你的代码和同学的几乎相同,但他的AC了,你的却TLE了
遇到这些情况,你可能要花上一个多小时才能解决,甚至难以解决,将问题一直搁置。不过,下ma下面有一种方法,可以让你的代码快许多。如果你有上面的第二种情况,那用这个方法,大概率能过。
怎么办
比如这一题:P6097 【模板】子集卷积
TLE代码
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[1<<21],b[1<<21],c[1<<21],ct[1<<21],ans[1<<21],ta[22][1<<21],tb[22][1<<21];
long long mod=1e9+9;
void fwt(long long *w,long long fl){for(int s=2;s<=(1<<n);s<<=1){int mid=s>>1;for(int v=0;v<(1<<n);v+=s){for(int i=0;i<mid;i++){w[v+mid+i]=(w[v+mid+i]+fl*w[v+i]+mod)%mod;}}}
}
int main()
{scanf("%d",&n);for(int i=1;i<(1<<n);i++){ct[i]=ct[i-(i&(-i))]+1;}for(int i=0;i<(1<<n);i++){scanf("%lld",&a[i]);ta[ct[i]][i]=a[i];}for(int i=0;i<(1<<n);i++){scanf("%lld",&b[i]);tb[ct[i]][i]=b[i];}for(int i=0;i<=n;i++){fwt(ta[i],1);fwt(tb[i],1);}for(int i=0;i<=n;i++){for(int j=0;j<=i;j++){for(int k=0;k<(1<<n);k++){c[k]=(c[k]+ta[j][k]*tb[i-j][k]%mod)%mod;}}fwt(c,-1);for(int j=0;j<(1<<n);j++){if(ct[j]==i) ans[j]=c[j];c[j]=0;}}for(int i=0;i<(1<<n);i++){printf("%lld ",ans[i]);}return 0;
}
这个方法是正解,代码也没有太大的问题,但就是TLE了。
但是,如果我在 m o d mod mod的变量定义前加上 c o n s t const const,也就是在第五行行首加上 c o n s t const const,就能AC了。
AC代码
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[1<<21],b[1<<21],c[1<<21],ct[1<<21],ans[1<<21],ta[22][1<<21],tb[22][1<<21];
const long long mod=1e9+9;
void fwt(long long *w,long long fl){for(int s=2;s<=(1<<n);s<<=1){int mid=s>>1;for(int v=0;v<(1<<n);v+=s){for(int i=0;i<mid;i++){w[v+mid+i]=(w[v+mid+i]+fl*w[v+i]+mod)%mod;}}}
}
int main()
{scanf("%d",&n);for(int i=1;i<(1<<n);i++){ct[i]=ct[i-(i&(-i))]+1;}for(int i=0;i<(1<<n);i++){scanf("%lld",&a[i]);ta[ct[i]][i]=a[i];}for(int i=0;i<(1<<n);i++){scanf("%lld",&b[i]);tb[ct[i]][i]=b[i];}for(int i=0;i<=n;i++){fwt(ta[i],1);fwt(tb[i],1);}for(int i=0;i<=n;i++){for(int j=0;j<=i;j++){for(int k=0;k<(1<<n);k++){c[k]=(c[k]+ta[j][k]*tb[i-j][k]%mod)%mod;}}fwt(c,-1);for(int j=0;j<(1<<n);j++){if(ct[j]==i) ans[j]=c[j];c[j]=0;}}for(int i=0;i<(1<<n);i++){printf("%lld ",ans[i]);}return 0;
}
跑得快了许多。
后记
这个问题我之前就遇到过,但一直没有在意。直到今天我调这道题,调了半个多小时才发现这里的问题。我觉得如果不知道这一点,可能还要浪费更多的时间。
有时候不加 c o n s t const const就会TLE,加上就AC了。在洛谷上会这样,但在本地,不管加不加 c o n s t const const,跑的时间都差不多。