【loli的胡策】NOIP训练10.2(快速幂+树形期望dp)

来源:互联网 发布:淘宝卖家回复差评用语 编辑:程序博客网 时间:2024/05/16 00:36

T1:

这里写图片描述

题解:

我们发现在放字母的时候,第一位可以放m种,第二位只能放m-1种,第三位只能放m-2种,被前两位所限制,后面的也只能放m-2种,快速幂不解释
考试的时候不知道怎么想的觉得n是10^18会卡快速幂,然后就不想要最后10pts
其实把ksm的k设成longlong就A了。。。。。

代码:

#include <cstdio>#include <iostream>#include <cstring>#define LL long longusing namespace std;const int Mod=1e9+7;LL ksm(LL a,LL k){    LL ans=1;a%=Mod;    for (;k;k>>=1,a=a*a%Mod)      if (k&1) ans=ans*a%Mod;    return ans%Mod;}int main(){    freopen("anti.in","r",stdin);    freopen("anti.out","w",stdout);    int T,i,j,k;LL n,m;    scanf("%d",&T);    while (T--)    {        scanf("%lld%lld",&n,&m);        m%=Mod;        if (n==1){printf("%lld\n",m);continue;}        LL lj=m*(m-1)%Mod;        printf("%lld\n",ksm(m-2,n-2)*lj%Mod);    }}

T2:

这里写图片描述

题解:

其实就是树形dp,当时确实想的要dp,但是打了50pts就放那里了,后来也没细想
qu[i]表示儿子i的期望值;sum[i]表示所有儿子的期望和;g[i]表示i节点当根节点的时候的值

代码:

#include <cstdio>#include <iostream>#include <cstring>#define INF 1e9#define N 1000005using namespace std;int tot,nxt[N*2],point[N],v[N*2],a[N],out[N],father[N];double qu[N],sum[N],g[N];void addline(int x,int y){    ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; out[x]++;    ++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; out[y]++;}void dfs(int x,int fa){    father[x]=fa;    qu[x]=a[x];    if (out[x]==1 && x!=1) return;    for (int i=point[x];i;i=nxt[i])       if (v[i]!=fa)      {        dfs(v[i],x);        sum[x]+=qu[v[i]];//儿子的期望和       }    if (x!=1) qu[x]+=sum[x]/(double)(out[x]-1);    else qu[x]+=sum[x]/(double)out[x];}void work(int x,double up){    for (int i=point[x];i;i=nxt[i])      if (v[i]!=father[x])      {        double zoom;        if (out[x]>1) zoom=(sum[x]-qu[v[i]]+up)/(double)(out[x]-1)+a[x];else zoom=a[x];          g[v[i]]=(sum[v[i]]+zoom)/out[v[i]]+a[v[i]];        work(v[i],zoom);      }}int main(){    freopen("walking.in","r",stdin);    freopen("walking.out","w",stdout);    int n,i,j;    scanf("%d",&n);    for (i=1;i<=n;i++) scanf("%d",&a[i]);    for (i=1;i<n;i++)    {        int x,y;        scanf("%d%d",&x,&y);        addline(x,y);    }    dfs(1,0); g[1]=qu[1];    work(1,0);    int k=1;    for (i=2;i<=n;i++) if (g[k]>g[i]) k=i;    printf("%d",k);}
阅读全文
1 0
原创粉丝点击