https://vijos.org/p/1892
此题需要手动开栈:
int size=256<<20; //256MB char *p=(char*)malloc(size)+size; __asm__("movl %0, %%esp\n" :: "r"(p));
还需要卡评测机←十分的神
卡了30多次评测机终于屈服了,一开始我盲目乱提交,总是T,后来上网找了一下解决卡常数方法,如下:
解决卡常数的方法比较多样化,主要有重复交题,拼人品让测评机快一点,在代码末尾加上//orz+神犇名字等(注意:没加“//”可能导致运行时间直接变为0ms!)。很多计算机算法竞赛的专家也在钻研如何解决这一问题,所以类似ZKW线段树等可以有效减少常数的时间占用的方法也在不断被发现,今后还有很大的探索空间。
没错,从那之后我提交就在程序最后加// orz ...,把人差不多都%了个遍,但都是90分,%charge时只是80分,但当我%马神(Godder)时成功AC!所以以后被卡常时就%%Godder,说不定就能AC。OI隐藏技能
以下是我的ACcode,重点在倒数第二行,保我AC的那一行
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) inline const int max(const int &a,const int &b){return a>b?a:b;} inline const int min(const int &a,const int &b){return a<b?a:b;} const int N=2000005; struct charge{ int nxt,to; }e[N<<1]; int cnt=0,point[N],r[N],sr[N],et[N],f[N][2]; long long M,g[N][2]; void read(int &sum) { char c=getchar();sum=0; while (c<'0'||c>'9') c=getchar(); while ('0'<=c&&c<='9') sum=sum*10+c-48,c=getchar(); } void insect(int x,int y){e[++cnt].nxt=point[x];point[x]=cnt;e[cnt].to=y;} void dp(int x,int fa) { long long tp; int mx,j,sz=0; g[x][0]=1; for (int i=point[x];i;i=e[i].nxt) if (e[i].to!=fa) { j=e[i].to; dp(j,x); tp=0; mx=max(f[j][0],f[j][1]); f[x][0]+=mx; if (f[j][0]==mx) tp=g[j][0]; if (f[j][1]==mx) tp+=g[j][1]; g[x][0]=(g[x][0]*tp)%M; } for (int i=point[x];i;i=e[i].nxt) if (e[i].to!=fa) et[++sz]=e[i].to; r[sz+1]=0; sr[sz+1]=1; for3 (i,sz,1) { mx=max(f[et[i]][0],f[et[i]][1]); r[i]=r[i+1]+mx; tp=0; if (f[et[i]][0]==mx) tp=g[et[i]][0]; if (f[et[i]][1]==mx) tp+=g[et[i]][1]; sr[i]=(sr[i+1]*tp)%M; } long long sl=1; int l=0; for1 (i,1,sz) { mx=l+r[i+1]+f[et[i]][0]+1; if (mx>f[x][1]) { f[x][1]=mx; g[x][1]=((sl*sr[i+1])%M*g[et[i]][0])%M; } else if (mx==f[x][1]) g[x][1]=(g[x][1]+(((sl*sr[i+1])%M*g[et[i]][0])%M))%M; mx=max(f[et[i]][0],f[et[i]][1]); l+=mx; tp=0; if (f[et[i]][0]==mx) tp=g[et[i]][0]; if (f[et[i]][1]==mx) tp+=g[et[i]][1]; sl=(sl*tp)%M; } } void outit() { int mx=max(f[1][0],f[1][1]),ans=0; if (mx==f[1][0]) ans=g[1][0]; if (mx==f[1][1]) ans+=g[1][1]; printf("%d\n%lld\n",mx,ans%M); } int main() { int size=256<<20; //256MB char *p=(char*)malloc(size)+size; __asm__("movl %0, %%esp\n" :: "r"(p)); memset(point,0,sizeof(point)); memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); int n,i,x,y; read(n); for2 (i,1,n) { read(x); read(y); insect(x,y); insect(y,x); } scanf("%lld\n",&M); dp(1,-1); outit(); return 0; // orz Godder }
然后就行了。