P1297
Description
第
题有
个选项。
做对了每一题,但是在最终填答题卡的时候填挫了,即第
题的答案填到了第
题上。特别的,第
题的答案填到了第
题上 (我也是醉了)
求可怜的 的正确题数的期望。
Solution
容易得到,做对题数的期望就是每题做对的概率之和。
做对一题当且仅当本题的答案与上一题的答案相同。因此,第 题正确的概率为 。分母为选项的组合的数量,分子为第 空正确的答案组合的数量。
若 ,那么所以答案就是 。
提前构造出数组 即可。时间复杂度为 。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,A,B,C;
double ans=0.00;
int a[10000005];
signed main()
{
cin>>n>>A>>B>>C>>a[1];
for (int i=2;i<=n;i++) a[i]=(a[i-1]*A+B)%100000001;
for (int i=1;i<=n;i++) a[i]=a[i]%C+1;//3 2 4
a[0]=a[n];
for (int i=1;i<=n;i++)
{
double first=min(a[i],a[i-1])*1.00,second=a[i]*a[i-1];
ans+=first/second;
}
cout<<fixed<<setprecision(3)<<ans<<endl;
return 0;
}
P6154
Description
给定一个 个点, 条有向边的无环图,求出路径长度的期望。
Solution
本题有套路式做法,即求出所有路径的长度之和与路径的条数。为了求这两个量,我们使用 ,即状态设计 表示目前发现到 点的所有路径的长度之和, 表示目前发现到 点的路径的数量。
在大部分的图形dp或树形dp中,任何一个节点的 值均转移自源于与它相邻的节点。假设我们现在想要得到 与 的值,那么它们必须由 推到而来( 与 有一条无向边,其中 连向 )。所以得到状态转移:
①
②
①表示, 的值要加上被它连接的那个点( )的 值,因为 计算的那些路径均可以通过加一条边 连到 ,所以有 这一步。
②表示,
的值要加上一些东西。甚么东西?即,
计算的路径均可以通过加一条边
连到
,这样每条路径的长度都变长了1;因此不仅要加上
,还要加上
。
题解中的几位大佬都叫它记忆化搜索…… 可怜的dp啊~
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
int n,m,cnt=0,sumv=0,num=0;
int head[1000005],totl[1000005],cntl[1000005];
struct edge
{
int next;
int to;
}e[2000005];
inline void add_edge(int u,int v)
{
cnt++;
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
inline void dfs(int now)
{
if (cntl[now]!=0) return;
cntl[now]=1;
for (int i=head[now];i;i=e[i].next)
{
dfs(e[i].to);
cntl[now]=(cntl[now]+cntl[e[i].to])%mod;
totl[now]=(totl[now]+totl[e[i].to]+cntl[e[i].to])%mod;
}
}
int quick_power(int a,int b)
{
if (b==0) return 1;
int res=1;
for (;b;b=b>>1,a=(a*a)%mod)
{
if (b&1) res=(res*a)%mod;
}
return res;
}
inline int divide(int a,int b)
{
return (a*quick_power(b,mod-2))%mod;
}
signed main()
{
cin>>n>>m;
for (int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
add_edge(u,v);
}
for (int i=1;i<=n;i++)
{
if (cntl[i]==0) dfs(i);
}
for (int i=1;i<=n;i++) sumv=(sumv+totl[i])%mod;
for (int i=1;i<=n;i++) num=(num+cntl[i])%mod;
cout<<divide(sumv,num)<<endl;
return 0;
}
P2441
Description
给定一棵树,支持修改某个点的点权与询问最近的与该点有公共质因子的祖先。
Solution
今天做的第 题,用来练手的~ 暴力即可
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,q,root,cnt=0;
int visited[200005],head[200005],a[200005],father[200005];
struct edge
{
int next;
int to;
}e[2000005];
inline void add_edge(int u,int v)
{
cnt++;
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
inline void dfs(int now,int fath)
{
father[now]=fath;
for (int i=head[now];i;i=e[i].next)
{
if (e[i].to!=fath) dfs(e[i].to,now);
}
}
inline int dfs2(int last,int now,int w)
{
if (now==0) return -1;
if (__gcd(a[now],w)!=1&&last!=now) return now;
else return dfs2(last,father[now],w);
}
signed main()
{
cin>>n>>q;
for (int i=1;i<=n;i++) cin>>a[i];
for (int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
add_edge(u,v);
add_edge(v,u);
visited[v]=1;
}
for (int i=1;i<=n;i++)
{
if (visited[i]==0)
{
root=i;
break;
}
}
dfs(root,0);
for (int i=1;i<=q;i++)
{
int flag;
cin>>flag;
if (flag==1)
{
int rt;
cin>>rt;
cout<<dfs2(rt,rt,a[rt])<<endl;
}
else if (flag==2)
{
int rt,num;
cin>>rt>>num;
a[rt]=num;
}
}
return 0;
}
由于时间限制,本蒟蒻就说三道题啦~~~
https://www.luogu.com.cn/user/87064(PS: 这是我)