BestCoder Round #76 (div.2) A B C





链接:戳这里


DZY Loves Balls 
 Time Limit: 4000/2000 MS (Java/Others)   Memory Limit: 262144/262144 K (Java/Others)
问题描述
DZY喜欢玩球。

他有n个球,装进一个大盒子里。每个球上面都写着一个整数。

有一天他打算从盒子中挑两个球出来。他先均匀随机地从盒子中挑出一个球,记为A。他不把A放回盒子,然后再从盒子中均匀随机地挑出一个球,记为B。

如果A上的数字严格大于B上的数字,那么他就会感到愉悦。

现在告诉你每个球上的数字,请你求出他感到愉悦的概率是多少。
输入描述
第一行t,表示有t组数据。

接下来t组数据。每组数据中,第一行包含一个整数n,第二行包含n个用空格隔开的正整数ai,表示球上的数字。

(1≤t≤300,2≤n≤300,1≤a​i≤300)


输出描述
对于每个数据,输出一个实数答案,保留6位小数。
输入样例
2
3
1 2 3
3
100 100 100
输出样例
0.500000
0.000000


思路:两个for暴力找出符合条件的个数


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int T,n;
int a[1001],b[1001];
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int Y=n*(n-1);
        int X=0;
        for(int i=1;i<=n;i++){
            int num=0;
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                if(a[i]>a[j]) num++;
            }
            X+=num;
        }
        double ans=(double)X*1.0/Y;
        printf("%.6f\n",ans);
    }
    return 0;
}



DZY Loves Partition  
 Time Limit: 4000/2000 MS (Java/Others)   Memory Limit: 262144/262144 K (Java/Others)
问题描述
DZY喜欢拆分数字。他想知道能否把nn拆成恰好kk个不重复的正整数之和。

思考了一会儿之后他发现这个题太简单,于是他想要最大化这k个正整数的乘积。你能帮帮他吗?

由于答案可能很大,请模10^9+7输出。
输入描述
第一行t,表示有t组数据。

接下来tt组数据。每组数据包含一行两个正整数n,k。

(1≤t≤50,2≤n,k≤10​e9)
输出描述
对于每个数据,如果不存在拆分方案,输出-1−1;否则输出最大乘积模10^9 + 7之后的值。


输入样例
4
3 4
3 2
9 3
666666 2
输出样例
-1
2
24
110888111
Hint
第一组数据没有合法拆分方案。
第二组数据方案为3=1+2,答案为1×2=2
第三组数据方案为9=2+3+4,答案为2×3×4=24。注意9=3+3+3是不合法的拆分方案,因为其中包含了重复数字。
第四组数据方案为666666=333332+333334,答案为333332×333334=111110888888。注意要对10^9 + 7取模后输出。


思路:首先肯定的是连续的数乘积肯定最大,那么我们先判断sum(1,k)是否大于n

填充完了连续的k个数之后,处理多出的值得情况,其实这里已经很明显了,直接从后往前累加1


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int T,n;
int a[1001],b[1001];
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int Y=n*(n-1);
        int X=0;
        for(int i=1;i<=n;i++){
            int num=0;
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                if(a[i]>a[j]) num++;
            }
            X+=num;
        }
        double ans=(double)X*1.0/Y;
        printf("%.6f\n",ans);
    }
    return 0;
}


DZY Loves Connecting 
 Time Limit: 4000/2000 MS (Java/Others)   Memory Limit: 262144/262144 K (Java/Others)
问题描述
DZY有一棵n个结点的无根树,结点按照1∼n标号。

DZY喜欢树上的连通集。一个连通集S是由一些结点组成的集合,满足SS中任意两个结点u,v能够用树上的路径连通,且路径上不经过S之外的结点。显然,单独一个结点的集合也是连通集。

一个连通集的大小定义为它包含的结点个数,DZY想知道所有连通集的大小之和是多少。你能帮他数一数吗?

答案可能很大,请对10^9 + 7取模后输出。
输入描述
第一行t,表示有t组数据。
接下来tt组数据。每组数据第1行一个数n。第2∼n行中,第i行包含一个数pi,表示i与p​i有边相连。(1≤p​i​​ ≤i−1,2≤i≤n)

(n≥1,所有数据中的n之和不超过200000)
输出描述
每组数据输出一行答案,对10^9 + 7取模。
输入样例
2
1
5
1
2
2
3
输出样例
1
42
Hint
第二个样例中,树的4条边分别为(1,2),(2,3),(2,4),(3,5)。所有连通集分别是{1},{2},{3},{4},{5},{1,2},{2,3},{2,4},{3,5},{1,2,3},{1,2,4},{2,3,4},{2,3,5},{1,2,3,4},{1,2,3,5},{2,3,4,5},{1,2,3,4,5}。

 If you need a larger stack size, 
please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
Statistic | Submit | Clarifications | Back


思路:我们设定两个数组 val[i]和num[i] 分别代表当前节点的贡献,儿子数

计算当前的值贡献 val[i]=val[i]+val[i]*num[j]+val[j]*num[i]

这段代码的意思是在树上,当前节点的贡献值等于它的儿子的贡献乘以父亲原有的儿子+当前父亲的贡献乘以儿子的儿子数,似乎很难理解  那我就不说了  


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
#define mod 1000000007
using namespace std;
int T,n;
struct edge{
    int u,v,next;
}e[2000100];
int head[200010],tot;
ll val[200010],num[200010];
void init(){
    mst(head,-1);
    tot=0;
    for(int i=1;i<=n;i++) val[i]=num[i]=1;
}
void add(int u,int v){
    e[tot].u=u;
    e[tot].v=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
void DFS(int u,int fa){
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(v==fa) continue;
        DFS(v,u);
        val[u]=(val[u]+val[u]*num[v]+val[v]*num[u])%mod;
        num[u]=num[u]*(num[v]+1)%mod;
    }
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        init();
        for(int i=2;i<=n;i++){
            int x;
            scanf("%d",&x);
            add(i,x);
            add(x,i);
        }
        DFS(1,0);
        ll ans=0;
        for(int i=1;i<=n;i++){
            ans+=val[i];
            ans%=mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值