关于编译器优化
查看原帖
关于编译器优化
365654
封禁用户楼主2024/8/21 21:45
#include <bits/stdc++.h>
using namespace std;
const char ss[3]={'N','O','I'};
int d[2][33012][9];
char c[22];
int ans[22];
char b[22]; // This one [Line 7]
int main()
{
	int n,k;
    cin>>n>>k;
    int p=(1<<k)-1;
    for(int i=1;i<=k;i++)
    	cin>>c[i];
    for(int i=0;i<=2;i++)
    	for(int j=0;j<=2;j++)
    	{
    		memset(b,0,sizeof b);
    		for(int ii=1;ii<=k;ii++)
    		{
    			for(int jj=1;jj<=ii;jj++)
    				if(c[jj]==ss[i]||c[jj]==ss[j])
    				{
    					b[ii]=1;
    					break;
    				}
    			for(int jj=1;jj<=ii-1;jj++)
    				for(int kk=jj+1;kk<=ii;kk++)
    				if(c[jj]==ss[i]&&c[kk]==ss[j])
    				{
    					b[ii]=2;
    					break;
    				}
    		}
    		int a=0;
    		for(int ii=1,jj=1;ii<=k;ii++,jj<<=1)
    			if(b[ii]-b[ii-1]) a+=jj;
    		d[0][a][3*i+j]++;
    	}
    for(int i=3;i<=n;i++)
    {
    	memset(d[i&1],0,sizeof d[i&1]);
		for(int j=0;j<=p;j++)
			for(int l=0;l<=2;l++)
			{
    			memset(b,0,sizeof b);
    			for(int ii=1,jj=1;ii<=k;ii++,jj<<=1)
    				if(j&jj) b[ii]=b[ii-1]+1;
    				else b[ii]=b[ii-1];
    			for(int ii=k;ii>=1;ii--)
    				if(c[ii]==ss[l]&&b[ii]==b[ii-1]) b[ii]++;
    			for(int ii=1;ii<=k;ii++)
    				if(b[ii]<b[ii-1]) b[ii]=b[ii-1];
    			int a=0;
    			for(int ii=1,jj=1;ii<=k;ii++,jj<<=1)
    				if(b[ii]>b[ii-1]) a+=jj;
    			for(int kk=0,kkk=0;kk<=8;kk++,kkk+=3)
    			{
    			    if(kkk==9) kkk=0;
    				if(kk==1&&l==2) continue;
    				d[i&1][a][kkk+l]+=d[1-(i&1)][j][kk];
    				if(d[i&1][a][kkk+l]>=1000000007) d[i&1][a][kkk+l]-=1000000007;
    			}
			} 
	}
	for(int i=0;i<=p;i++)
		for(int j=0;j<=8;j++)
		{
			int o=0;
			for(int kk=1,ll=1;kk<=k;kk++,ll<<=1)
				if(i&ll) o++;
			ans[o]+=d[n&1][i][j];
			if(ans[o]>=1000000007) ans[o]-=1000000007;
		}
	for(int i=0;i<=k;i++)
		cout<<ans[i]<<endl;
    return 0;
}

上述代码第 77 行 b 数组的大小(≥16\ge 16)决定了该程序是否 AC(C++14 (GCC 9) O2 下):

  • 取 ≤18\le 18 时 TLE 40pts / 50pts,#8 用时均在 6.1s - 6.2s 之间;
  • 18→1918 \to 19 时 #8 用时突变;
  • 取 19∼3019\sim30 时 AC,#8 用时均在 5.7s - 5.8s 之间;
  • 30→3130 \to 31 时 #8 用时突变;
  • 取 ≥31\ge 31 时 TLE 50pts / 60pts,#8 用时均在 6.1s - 6.2s 之间。

所以这是什么奇怪的编译器优化?

2024/8/21 21:45
加载中...