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 long
using 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 1000005
using 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);
}