我貌似又做了一道高精题呢(笑)
这题的DP方程很好想,设f[i][j]表示i为根的子树,i所在联通块大小为j的最大值,然后乱搞
但是要高精,那么搞是得要高精除的
所以考虑f[i][j]是除以j后的最大值,就可以只写高精乘了
不过卡常,下面代码只能得95分
// luogu-judger-enable-o2 // luogu-judger-enable-o2 #include<cstdio> #include<iostream> #include<cctype> #include<cstring> #include<cstdlib> #include<algorithm> #define maxl 120 #define maxn 702 #define check(x) if(x==0) x=++tot; using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch==‘-‘) f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-‘0‘; ch=getchar(); } return num*f; } struct BigInteger{ int s[maxl],len; BigInteger(){len=0;memset(s,0,sizeof(s));} BigInteger operator =(const char *c){ len=0; for(int i=strlen(c+1);i;--i) s[++len]=c[i]-‘0‘; return *this; } BigInteger operator =(const int num){ char c[maxl]; sprintf(c+1,"%d",num); (*this)=c; return *this; } BigInteger operator *(BigInteger a){ BigInteger ans; ans.len=len+a.len; for(int i=1;i<=len;++i) for(register int j=1;j<=a.len;++j) ans.s[i+j-1]+=s[i]*a.s[j]; int g=0; for(int i=1;i<=(len+a.len)||g;++i){ ans.s[i]+=g; g=ans.s[i]/10; ans.s[i]%=10; if(ans.len<i) ans.len=i; } while(ans.len&&ans.s[ans.len]==0) ans.len--; return ans; } BigInteger operator *(const int a){ BigInteger ans=(*this); int g=0,lim=ans.len; for(int i=1;(i<=lim)||g;++i){ ans.s[i]=ans.s[i]*a+g; g=ans.s[i]/10; ans.s[i]%=10; if(i>ans.len) ans.len=i; } while(ans.len&&ans.s[ans.len]==0) ans.len--; return ans; } bool operator <(const BigInteger a)const{ if(len!=a.len) return len<a.len; for(int i=len;i;--i) if(s[i]!=a.s[i]) return s[i]<a.s[i]; return 0; } }; inline void print(BigInteger a){ if(a.len==0) putchar(‘0‘); for(int i=a.len;i;--i) putchar(a.s[i]+‘0‘); } BigInteger f[maxn*350]; int tot; int size[maxn]; int pos[maxn][maxn]; BigInteger ans; struct Edge{ int next,to; }edge[maxn*3]; int head[maxn],num; inline void add(int from,int to){ edge[++num]=(Edge){head[from],to}; head[from]=num; } void dfs(int x,int fa){ check(pos[x][0]); check(pos[x][1]); f[pos[x][0]]=1;f[pos[x][1]]=1; size[x]=1; for(int i=head[x];i;i=edge[i].next){ int to=edge[i].to; if(to==fa) continue; dfs(to,x); size[x]+=size[to]; for(int j=size[x];j>=0;--j){ check(pos[x][j]); for(int k=min(j,size[x]-size[to]);k>=min(1,size[x]-size[to]);--k) if(f[pos[x][j]]<f[pos[to][j-k]]*f[pos[x][k]]){ f[pos[x][j]]=f[pos[to][j-k]]*f[pos[x][k]]; } } } for(int j=1;j<=size[x];++j){ if(f[pos[x][0]]<f[pos[x][j]]*j){ f[pos[x][0]]=f[pos[x][j]]*j; if(ans<f[pos[x][0]]) ans=f[pos[x][0]]; } } } int main(){ int n=read(); for(int i=1;i<n;++i){ int x=read(),y=read(); add(x,y); add(y,x); } dfs(1,1); print(ans); }