标签:nbsp can += dfs 思维 考试 event log 多重
考试时先看的第一题
一看好像不可做的样子
然后我去做三了,
5分钟打完tpy==0的情况,然后开始tpy==2
一看tpy==2看起来最简单,然后开始推,推了很久没有推出来,
然后我去看tpy==3???
我为什么要看==3,
我不知道,可能我觉得3推出来1就可以推出来了,毕竟1比较简单
然后我没推出来,我就开始打表了
没看出来规律,我就列各种式子
if(k==1){ for(ll i=0;i<=m;i++) ans=(ans+C(2*i,i)%mod*meng(i+1,mod-2)%mod*jie[n-2*i]*(ni[m-i]%mod*ni[m-i]%mod)%mod)%mod;
什么Catalan数,多重集排列往上扔
连样例也过不了
然后我就滚回去做第二题了
再一看,
好像树归不可做,然后图论不可做
对于==1时打个点分治吧!
然后我点分治打完连样例也过不了
终于调出来之后
对于==2时打个gauss消元吧!
然后我gauss开的long long??????
然后就0分了
代码
#include<bits/stdc++.h> #define ll long long #define Inf 1e9+7 #define mem(a) memset(a,0,sizeof(a)) #define A 1000000 using namespace std; ll tot=0,head[A],a[A],b[A],nxt[A],ver[A],deep[A],dis[A]; double gs[110][110],d[A]; ll f[A][30],ans[A],sz[A]; ll n,m,q,t,cnt=0,mx,toot,top=0,tk,size; bool flag[A],vis[A]; void add(ll x,ll y){ nxt[++tot]=head[x],head[x]=tot,ver[tot]=y; } inline ll lca(ll x,ll y){ if(deep[x]>deep[y]) swap(x,y); ll w; for(w=0;(1<<w)<=deep[y];w++); w--; for(ll i=w;i>=0;i--) { if(deep[x]<=deep[f[y][i]]) y=f[y][i]; if(deep[x]==deep[y]) break; } if(x==y) return x; for(ll i=w;i>=0;i--){ if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; } return f[y][0]; } void dfs(ll x,ll de){ deep[x]=de;flag[x]=1; for(ll i=head[x];i;i=nxt[i]){ ll y=ver[i]; if(flag[y]) continue; f[y][0]=x; dfs(y,de+1); } } void re(){ mem(head),mem(dis),mem(nxt),mem(ver),mem(b),mem(d),mem(vis); } void gettoot(ll x,ll fa){ ll num=0; sz[x]=1; for(ll i=head[x];i;i=nxt[i]){ ll y=ver[i]; if(vis[y]||y==fa) continue; gettoot(y,x); sz[x]+=sz[y]; num=max(num,sz[y]); } num=max(num,size-sz[x]); if(num<mx) mx=num,toot=x; } void getdiss(ll x,ll fa,ll dep){ for(ll i=head[x];i;i=nxt[i]){ ll y=ver[i]; if(vis[y]||y==fa) continue; d[y]=d[x]+1; getdiss(y,x,dep); if(dep==0) b[x]+=d[x]-d[y]; else b[x]-=d[x]-d[y]; } } void calc(ll x,ll dep){ d[x]=dep; getdiss(x,0,dep); } ll solve(ll x){ calc(x,0); vis[x]=1; for(ll i=head[x];i;i=nxt[i]){ ll y=ver[i]; calc(x,1); mx=Inf; size=sz[y]; gettoot(y,0); solve(y); } } void gauss(){ for(ll i=1;i<=n;i++){ ll z=i,maxn=0; for(ll j=i;j<=n;j++) if(gs[i][j]>maxn) z=j,maxn=gs[i][j]; if(z!=i) for(ll j=1;j<=n+1;j++) swap(gs[i][j],gs[z][j]); for(ll j=n;j>=i;j--) for(ll k=1;k<=n;k++) if(k!=j) gs[i][j]=gs[i][j]/gs[i][i]; } } int main(){ ll T; scanf("%lld",&T); while(T--) { re(); scanf("%lld",&n); t=log(n)/log(2)+5; for(ll i=1;i<n;i++){ ll x,y; scanf("%lld%lld",&x,&y); add(x,y);add(y,x); } scanf("%lld",&tk); for(ll i=1;i<=n;i++) scanf("%lld",&a[i]); if(n<=1000){ dfs(1,1),f[1][0]=1; for(ll j=1;j<=t;j++) for(ll i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++) if(j==i) continue; else{ ll lc=lca(i,j); ll di=deep[i]+deep[j]-2*deep[lc]; b[i]+=a[j]*di; } for(ll i=1;i<=n;i++){ printf("%lld ",b[i]); } printf("\n"); } else{ mx=Inf; size=n; gettoot(1,0); solve(toot); for(ll i=1;i<=n;i++){ printf("%lld ",b[i]); } printf("\n"); } } } //我竟然用傻逼点分治
这几次考得最差一回,只有30分
思维一度僵化,
总是想把题套路化,第三题其实考试之前做过一个类似的题
但我没有迁移过去,只是无意义的凑数,想把自己式子凑到打的表上。
最终我连简单Catalan数都没看出来。
还是强调思维发散。
标签:nbsp can += dfs 思维 考试 event log 多重
原文地址:https://www.cnblogs.com/znsbc-13/p/11254493.html