2018“百度之星”程序设计大赛 - 复赛

没有兄弟的舞会

Accepts: 928

Submissions: 2446

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

Problem Description

度度熊、光羽、带劲三个人是好朋友。

度度熊有一棵nn个点的有根树,其中1号点为树根。除根节点之外,每个点都有父节点,记ii号点的父节点为fa[i]fa[i]。

度度熊称点ii和点jj是兄弟(其中i \neq ji≠j)当且仅当fa[i]=fa[j]fa[i]=fa[j]。

第ii个点的权值为A_iA?i??。现要求选出一个点集,该点集合法当且仅当点集中至多只有一对兄弟。

度度熊想知道,在所有可行的点集中,权值和最大以及最小的点集权值和分别是多少?

Input

第一行一个数,表示数据组数TT。

每组数据第一行一个整数nn;第二行n-1n?1个数,表示fa[2],fa[3],..,fa[n]fa[2],fa[3],..,fa[n];第三行nn个数,表示A_iA?i??。

数据组数T=100,满足:

  • 1 \le n \le 10^51≤n≤10?5??
  • -10^9 \le A_i \le 10^9?10?9??≤A?i??≤10?9??
  • 1 \le fa[i] < i1≤fa[i]<i

其中90%的数据满足n \le 1000n≤1000。

Output

每组数据输出一行,每行包含两个数,分别表示权值和的最大值和最小值。

Sample Input

Copy

2
5
1 1 2 2
-4 -4 -1 -2 -5
5
1 1 3 2
-1 -4 2 0 -2 

Sample Output

0 -15
2 -7


这个对我来说有点hard啊,我比较傻,要选的是点集,不一定是子树,所以即使是树形dp也不是全都可以选的,所以可以直接sort之后取一个就好了

另外一个直接找就好了

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define pb push_back
#define fi first
#define se second
#define ll long long
#define sz(x) (int)(x).size()
#define pll pair<long long,long long>
#define pii pair<int,int>
#define pq priority_queue
const int N=1e5+5,MD=1e9+7,INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9,e=exp(1),PI=acos(-1.);
vector<ll>G[N];
ll a[N],x;
int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int T,n;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=2; i<=n; i++)cin>>a[i];
        for(int i=1; i<=n; i++)cin>>x,G[a[i]].push_back(x);
        ll ma=0,mi=0,minx=1e9,maxx=-1e9;
        for(int i=0; i<=n; i++)
        {
            sort(G[i].begin(),G[i].end());
            int len=G[i].size();
            if(len)
            {
                ma=max(ma,ma+G[i][len-1]),mi=min(mi,mi+G[i][0]);
                if(len>1)minx=min(minx,G[i][1]),maxx=max(maxx,G[i][len-2]);
            }
        }
        mi=min({mi,mi+minx,0LL}),ma=max({ma,maxx+ma,0LL});
        cout<<ma<<" "<<mi<<"\n";
        for(int i=0; i<=n; i++)G[i].clear();
    }
    return 0;
}

带劲的and和

Accepts: 791

Submissions: 2435

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

Problem Description

度度熊专门研究过“动态传递闭包问题”,他有一万种让大家爆蛋的方法;但此刻,他只想出一道简简单单的题——至繁,归于至简。

度度熊有一张n个点m条边的无向图,第ii个点的点权为v_iv?i??。

如果图上存在一条路径使得点ii可以走到点jj,则称i,ji,j是带劲的,记f(i,j)=1f(i,j)=1;否则f(i,j)=0f(i,j)=0。显然有f(i,j) = f(j,i)f(i,j)=f(j,i)。

度度熊想知道求出: \sum_{i=1}^{n-1} \sum_{j=i+1}^{n} f(i,j) \times \max(v_i, v_j) \times (v_i \& v_j)∑?i=1?n?1??∑?j=i+1?n??f(i,j)×max(v?i??,v?j??)×(v?i??&v?j??)

其中\&&是C++中的and位运算符,如1&3=1, 2&3=2。

请将答案对10^9+710?9??+7取模后输出。

Input

第一行一个数,表示数据组数TT。

每组数据第一行两个整数n,mn,m;第二行nn个数表示v_iv?i??;接下来mm行,每行两个数u,vu,v,表示点uu和点vv之间有一条无向边。可能有重边或自环。

数据组数T=50,满足:

  • 1 \le n,m \le 1000001≤n,m≤100000
  • 1 \le v_i \le 10^91≤v?i??≤10?9??。

其中90%的数据满足n,m \le 1000n,m≤1000。

Output

每组数据输出一行,每行仅包含一个数,表示带劲的and和。

Sample Input

Copy

1
5 5
3 9 4 8 9
2 1
1 3
2 1
1 2
5 2

Sample Output

99


其实就是每一个联通块要算贡献,这个联通块是可以用二进制压缩的,所以并查集找出联通块直接暴力就好了

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define pb push_back
#define fi first
#define se second
#define ll long long
#define sz(x) (int)(x).size()
#define pll pair<long long,long long>
#define pii pair<int,int>
#define pq priority_queue
const int N=1e5+5,MD=1e9+7,INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9,e=exp(1),PI=acos(-1.);
int fa[N],v[N];
vector<int>G[N];
int find(int x)
{
    return x==fa[x]?x:(fa[x]=find(fa[x]));
}
void la(int x,int y)
{
    x=find(x),y=find(y);
    if(x!=y)fa[x]=y;
}
int bit[31];
ll lb(vector<int>v)
{
    sort(v.begin(),v.end());
    ll ans=0,sum[31]= {0};
    for(auto t:v)
        for(int j=0; j<30; j++)
        {
            if(t&bit[j])
            {
                ans=(ans+t*1LL*sum[j]%MD*bit[j]%MD)%MD;
                sum[j]++;
            }
        }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    for(int i=0; i<30; i++)bit[i]=1<<i;
    int T,n,m;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        for(int i=1; i<=n; i++)cin>>v[i];
        for(int i=1; i<=n; i++)fa[i]=i;
        for(int i=0,u,v; i<m; i++)
            cin>>u>>v,la(u,v);
        for(int i=1; i<=n; i++)G[find(i)].push_back(v[i]);
        int ans=0;
        for(int i=1; i<=n; i++)
        {
            if(G[i].size()==0)continue;
            ans=(ans+lb(G[i]))%MD;
        }
        cout<<ans<<"\n";
        for(int i=1; i<=n; i++)G[i].clear();
    }
    return 0;
}

序列期望

Accepts: 545

Submissions: 1163

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

Problem Description

"看似随机,实则早已注定"——光羽

度度熊有nn个随机变量x_1,x_2,...,x_nx?1??,x?2??,...,x?n??。给定区间[l_1, r_1],...,[l_n, r_n][l?1??,r?1??],...,[l?n??,r?n??],变量x_ix?i??的值会等概率成为区间[l_i, r_i][l?i??,r?i??]中的任意一个整数。

显然这nn个随机变量的值会有一共\prod_{i=1}^{n} (r_i - l_i + 1)∏?i=1?n??(r?i???l?i??+1) 种情况,且每种情况出现的概率为\prod_{i=1}^{n} \frac{1}{r_i - l_i + 1}∏?i=1?n???r?i???l?i??+1??1?? 。

对于某种情况,令h= \max{ x_1,x_2,...,x_n}h=max{x?1??,x?2??,...,x?n??},定义这种情况的权值为:\prod_{i=1}^{n} (h - x_i + 1)∏?i=1?n??(h?x?i??+1).

度度熊想知道权值的期望是多少?请将答案对10^9 + 710?9??+7取模后输出。

PS:不清楚期望是啥?为什么不问问神奇的百度呢?

Input

第一行一个数,表示数据组数TT。

每组数据第一行一个整数nn;接下来nn行,每行两个数,表示l_il?i??和r_ir?i??。

数据组数T=100,满足:

  • 1 \le n \le 1001≤n≤100
  • 1 \le l_i \le r_i \le 10^41≤l?i??≤r?i??≤10?4??

其中70%的数据满足r_i \le 100r?i??≤100。

Output

每组数据输出一行,每行仅包含一个数,表示期望。

假设答案为\frac{p}{q}?q??p??,请输出p \times q^{-1} ~mod~10^9+7p×q??1?? mod 10?9??+7,此处q^{-1}q??1??为qq的逆元。

Sample Input

2
3
2 5
2 4
2 5
3
1 1
2 3
1 1

Sample Output

Copy

875000012
500000010

Hint

第二组数据的解释:序列只有两种情况(1,2,1)和(1,3,1),权值分别为2*1*2=4和3*1*3=9,答案为(4+9)/2,在模域下为500000010。

这个题目看起来好像不可做,其实就是简单的期望,我们只要想到权值的统计方法就好了

显然我们可以枚举最大的区间

原文地址:https://www.cnblogs.com/BobHuang/p/9501607.html

时间: 2024-10-10 05:25:51

2018“百度之星”程序设计大赛 - 复赛的相关文章

2018 “百度之星”程序设计大赛 - 复赛

1001 没有兄弟的舞会 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 100005; int t,n; int a[maxn],fa[maxn]; struct node { int to,w; node(){} node(int _to,int _w) { to=_to;w=_w; } bool operator < (const node & _nod

2017&quot;百度之星&quot;程序设计大赛 - 复赛1005&amp;&amp;HDU 6148 Valley Numer【数位dp】

Valley Numer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 311    Accepted Submission(s): 165 Problem Description 众所周知,度度熊非常喜欢数字. 它最近发明了一种新的数字:Valley Number,像山谷一样的数字. 当一个数字,从左到右依次看过去数字没有出现先递增接

2017&quot;百度之星&quot;程序设计大赛 - 复赛1003&amp;&amp;HDU 6146 Pok&#233;mon GO【数学,递推,dp】

Pokémon GO Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 171    Accepted Submission(s): 104 Problem Description 众所周知,度度熊最近沉迷于 Pokémon GO. 今天它决定要抓住所有的精灵球! 为了不让度度熊失望,精灵球已经被事先放置在一个2*N的格子上,每一个格子上都

2017&quot;百度之星&quot;程序设计大赛 - 复赛1001&amp;&amp;HDU 6144 Arithmetic of Bomb【java大模拟】

Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 129    Accepted Submission(s): 94 Problem Description 众所周知,度度熊非常喜欢数字. 它最近在学习小学算术,第一次发现这个世界上居然存在两位数,三位数……甚至N位数! 但是这回的算术题可并不简单,由于

2018&quot;百度之星&quot;程序设计大赛 - 资格赛 - 题集

1001 $ 1 \leq m \leq 10 $ 像是状压的复杂度. 于是我们(用二进制)枚举留下的问题集合 然后把这个集合和问卷们的答案集合 $ & $ 一下 就可以只留下被选中的问题的答案了. 之后扫一遍随便判一下重. 1002 非空子串中字典序最小的子串长度一定是 $ 1 $ . 咱们就记录一下每一个字母出现次数的前缀和, 每次询问就找到出现过的最先的那个字符就星了. 1003 整数规划好像是个NPC问题, 所以我们肯定不能直接上整数规划. 咱们来尝试把问题转换一下. n=2 x1---

2018 “百度之星”程序设计大赛 - 初赛(A)

第二题还算手稳+手快?最后勉强挤进前五百(期间看着自己从两百多掉到494名) 1001  度度熊拼三角    (hdoj 6374) 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6374 签到题 题意:给n根木棒 求可以拼出的周长最长的三角形 可以用贪心的思想做 对所有的木棒长度进行排序 取最长的三根进行判断是否可以组成三角形 若不能 舍去最长的一根 每次都选择相邻的三根 for一遍就好 复杂度为O(nlogn) 代码如下 #include <ios

2018 “百度之星”程序设计大赛 - 初赛(A)1004 / hdu6377 度度熊看球赛 dp递推

度度熊看球赛 Problem Description 世界杯正如火如荼地开展!度度熊来到了一家酒吧. 有 N 对情侣相约一起看世界杯,荧幕前正好有 2×N 个横排的位置. 所有人都会随机坐在某个位置上. 当然,如果某一对情侣正好挨着坐,他们就会有说不完的话,影响世界杯的观看. 一般地,对于一个就座方案,如果正好有 K 对情侣正好是挨着坐的,就会产生 DK 的喧闹值. 度度熊想知道随机就座方案的期望喧闹值. 为了避免输出实数,设答案为 ans,请输出 ans×(2N)! mod P 的值.其中 P

2018&quot;百度之星&quot;程序设计大赛 - 资格赛

调查问卷 Accepts: 1546 Submissions: 6596 Time Limit: 6500/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Problem Description 度度熊为了完成毕业论文,需要收集一些数据来支撑他的论据,于是设计了一份包含 mm 个问题的调查问卷,每个问题只有 'A' 和 'B' 两种选项. 将问卷散发出去之后,度度熊收到了 nn 份互不相同的问卷,在整理结果的时候

2018 “百度之星”程序设计大赛 - 初赛(B)

degree Accepts: 1581 Submissions: 3494 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Description 度度熊最近似乎在研究图论.给定一个有 NN 个点 (vertex) 以及 MM 条边 (edge) 的无向简单图 (undirected simple graph),此图中保证没有任何圈 (cycle) 存在. 现在