• [BZOJ5250][九省联考2018]秘密袭击(DP)


    5250: [2018多省省队联测]秘密袭击

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 3  Solved: 0
    [Submit][Status][Discuss]

    Description

    【题目背景】
    We could have had it all. . . . . .
    我们本该,拥有一切
    Counting on a tree. . . . . .
    何至于此,数数树上
    Counting on a Tree( CoaT)即是本题的英文名称。
    【题目描述】
    AccessGlobe最近正在玩一款战略游戏。在游戏中,他操控的角色是一名C国士兵。他的任务就是服从指挥官的指令
    参加战斗,并在战斗中取胜。C国即将向D国发动一场秘密袭击。作战计划是这样的:选择D国的s个城市,派出C国
    战绩最高的s个士兵分别秘密潜入这些城市。每个城市都有一个危险程度di,C国指挥官会派遣战绩最高的士兵潜入
    所选择的城市中危险程度最高的城市,派遣战绩第二高的士兵潜入所选择的城市中危险程度次高的城市,以此类推
    (即派遣战绩第i高的士兵潜入所选择城市中危险程度第i高的城市)。D国有n个城市,n-1条双向道路连接着这些
    城市,使得这些城市两两之间都可以互相到达。为了任务执行顺利,C国选出的s个城市中,任意两个所选的城市,
    都可以不经过未被选择的城市互相到达。AccessGlobe操控的士兵的战绩是第k高,他希望能估计出最终自己潜入的
    城市的危险程度。AccessGlobe假设C国是以等概率选出任意满足条件的城市集合S,他希望你帮他求出所有可能的
    城市集合中,AccessGlobe操控的士兵潜入城市的危险程度之和。如果选择的城市不足k个,那么AccessGlobe不会
    被派出,这种情况下危险程度为0。当然,你并不想帮他解决这个问题,你也不打算告诉他这个值除以998,244,353
    的余数,你只打算告诉他这个值除以64,123的余数。

    Input

    第1行包含3个整数n、k、W
    表示D国城市的个数、AccessGlobe所操控士兵潜入的城市战绩排名以及D国的所有城市中最大的危险程度;
    第2行包含n个1到W之间的整数d1,d2,...,dn,表示每个城市的危险程度;
    第3行到第n+1行,每行两个整数xi,yi,表示D国存在一条连接城市xi和城市yi的双向道路
    1 ≤ k ≤ n,, 1 ≤ di ≤ W, n, k, W ≤ 1, 666。

    Output

    输出一个整数,表示所有可行的城市集合中
    AccessGlobe操控的士兵潜入城市的危险程度之和除以64,123的余数。

    Sample Input

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

    Sample Output

    11

    HINT

     请不要提交,原题空间限制为1G,单点时限5s.请下载数据自行测评.数据如下:https://begin.lydsy.com/JudgeOnline/upload/5240.rar

    Source

    [Submit][Status][Discuss]

    正解好像是从本质理解FFT?听起来就不可做。

    考虑暴力踩标程。我们枚举每个点,算出以这个点为第k名的连通块个数。

    我们将枚举的点作为根DP,因为可能有重复,所以规定相等的点只能从编号小的走向大的,这题就成了某道CF原题了。

    下面代码的主要思想是,递归时由父亲将信息传下来,然后修改当前点的信息,然后递归到子节点完善信息,再将信息返回给父亲。这个思路感觉比较新奇。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=l; i<=r; i++)
     5 using namespace std;
     6 
     7 const int N=4010,mod=64123;
     8 int n,k,W,cnt,S,ans,u,v,to[N<<1],nxt[N<<1],h[N],d[N],f[N][N];
     9 
    10 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
    11 void up(int &x,int y){ x+=y; if (x>=mod) x-=mod; }
    12 
    13 void dfs(int x,int fa,int g[]){
    14     if (d[x]>d[S] || (d[x]==d[S] && x>S)) rep(i,1,k) f[x][i]=g[i-1];
    15         else rep(i,1,k) f[x][i]=g[i];
    16     for (int i=h[x]; i; i=nxt[i]) if (to[i]!=fa) dfs(to[i],x,f[x]);
    17     rep(i,1,k) up(g[i],f[x][i]);
    18 }
    19 
    20 void calc(int x){
    21     int tot=1;
    22     rep(i,1,n) if (d[i]>d[x] || (d[i]==d[x] && i>x)) tot++;
    23     if (tot<k) return;
    24     S=x; memset(f[x],0,sizeof(f[x])); f[x][1]=1;
    25     for (int i=h[x]; i; i=nxt[i]) dfs(to[i],x,f[x]);
    26     ans=(ans+1ll*d[x]*f[x][k])%mod;
    27 }
    28 
    29 int main(){
    30     freopen("coat.in","r",stdin);
    31     freopen("coat.out","w",stdout);
    32     scanf("%d%d%d",&n,&k,&W);
    33     rep(i,1,n) scanf("%d",&d[i]);
    34     rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
    35     rep(i,1,n) calc(i);
    36     printf("%d
    ",ans);
    37     return 0;
    38 }
  • 相关阅读:
    ThinkPHP实现定时任务
    VUE 父子组件之间通信传值 props和 $emit,事件触发传值ref,以及兄弟组件之间的通信传值 eventBus
    JS链接转换为二维码
    VUE 动态切换列表active样式
    微信内置浏览器video标签自动全屏的问题
    JS监听video视频播放时间
    JS数据统计表 highcharts.js的运用
    JS 自动返回每个月的天数
    JS 一键复制插件应用 和 原生实现
    JS enter键一键登录
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8742686.html
Copyright © 2020-2023  润新知