题目

一颗二叉树,每个点儿子个数为0 或 2 ,对每个叶子有一个权值\((c(u),d(u))\)

从根结点开始走,Alice 可以选择奇数层的走法,Bob 可以选择偶数层的走法,分别获得最后走到叶子的c,d权值

设Alice的策略为f,Bob的策略为g,对于确定的(c,d),一个(f,g)是nash均衡的当且仅当:

1.f不变,改变g都不能使得Bob获得的数更大 ; 2.g不变,改变f的值都不能使得Alice获得的数更大;

求叶子的权值范围为\((1-K,1-K)\)的nash均衡点的个数和

$n \le 5000 \ , \ K \le 20 $

题解

  • 做法一:

  • 枚举最后选到的(C,D),设\(f_{u,0/1,0/1,0/1}\)表示当前子树,改变奇数层能否让\(C\)更大,改变偶数层能否让\(D\)更大,能否走到\((C,D)\)按照定义转移即可;

  • 时间复杂度:\(O(64nK^2)\)

  • 做法二:

  • 对于一种(c,d),nash点的个数就是\(|f| \times |g|\) 的矩形上鞍点的个数

  • 对于矩形上的每个点是相对独立的

  • 所以\(f\)和\(g\)只要知道了有多少个不同的叶子节点也是独立的

  • 设\(f_i\)表示改变\(g\),有多少个\(f\)选到的叶子节点的集合大小为\(i\),\(g_i\)同理,按照定义\(dp\)

  • 设\(p_i = \sum_{j=1}^{K} j^{i-1}\)答案就是\(K^{ 2L } \times (\sum_{i=1}^{K}\frac{f_ip_i}{K^i}) \times ( \sum_{ j=1 }^{ K } \frac{g_jp_j}{K^j})\)

  • 复杂度:\(O(n ^ 2)\)

  • 有个奇怪的问题:

  • 由于改变\(f\)和改变\(g\)得到的点的集合除了选到的点以外都是不相交的,

  • 这意味着二维权值这个条件可能是彻底没有用的。。。。。。。。

    //sol 1 :
    #include<bits/stdc++.h>
    #define mod 998244353
    #define pb push_back using namespace std; const int N=5010;
    int n,K,fa[N],ch[N][2],dep[N],dp[N][2][2][2],C1,C2;
    vector<int>sn[N]; void inc(int&x,int y){x+=y;if(x>=mod)x-=mod;} void dfs(int k){
    if(!sn[k].size()){
    dp[k][0][0][0]=C1*C2-1;
    dp[k][0][0][1]=1;
    dp[k][0][1][0]=C1*(K-C2);
    dp[k][1][0][0]=(K-C1)*C2;
    dp[k][1][1][0]=(K-C1)*(K-C2);
    return ;
    }
    int l=sn[k][0],r=sn[k][1];
    dfs(l);dfs(r);
    memset(dp[k],0,sizeof(dp[k]));
    for(int a1=0;a1<2;++a1)
    for(int b1=0;b1<2;++b1)
    for(int c1=0;c1<2;++c1)
    for(int a2=0;a2<2;++a2)
    for(int b2=0;b2<2;++b2)
    for(int c2=0;c2<2;++c2){
    int tmp=1l*dp[l][a1][b1][c1]*dp[r][a2][b2][c2]%mod;
    if(!(dep[k]&1)){
    inc(dp[k][a1|a2][b1][c1],tmp);
    inc(dp[k][a1|a2][b2][c2],tmp);
    }else{
    inc(dp[k][a1][b1|b2][c1],tmp);
    inc(dp[k][a2][b1|b2][c2],tmp);
    }
    }
    } int main(){
    freopen("nash.in","r",stdin);
    freopen("nash.out","w",stdout);
    scanf("%d%d",&n,&K);
    for(int i=2;i<=n;++i){
    scanf("%d",&fa[i]);fa[i]++;
    sn[fa[i]].pb(i);
    dep[i]=dep[fa[i]]+1;
    }
    int ans=0;
    for(C1=1;C1<=K;++C1)
    for(C2=1;C2<=K;++C2){
    dfs(1);
    inc(ans,dp[1][0][0][1]);
    }
    cout<<ans<<endl;
    return 0;
    }
    //sol 2 :
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #define PII pair<int,int>
    #define MP make_pair
    #define fir first
    #define sec second
    #define PB push_back
    #define db long double
    #define ll long long
    using namespace std;
    template <class T>
    inline void rd(T &x) {
    x=0; char c=getchar(); int f=1;
    while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); }
    while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f;
    }
    const int N=5010,mod=998244353;
    int Pow(int x,int y) {
    int res=1;
    while(y) {
    if(y&1) res=res*(ll)x%mod;
    x=x*(ll)x%mod,y>>=1;
    }
    return res;
    }
    int h[2][N][N],n,L;
    int son[N][2],fa[N],sz[N];
    int dep[N];
    void dfs(int u) {
    if(!son[u][0]) return (void)(h[0][u][1]=h[1][u][1]=1,sz[u]=1);
    dfs(son[u][0]),dfs(son[u][1]);
    sz[u]+=sz[son[u][0]]+sz[son[u][1]];
    for(int c=0;c<2;++c) {
    if(c==dep[u]) {
    int cnt0=0,cnt1=0;
    for(int j=1;j<=L;++j) {
    cnt0=(cnt0+h[c][son[u][0]][j])%mod;
    cnt1=(cnt1+h[c][son[u][1]][j])%mod;
    }
    for(int j=1;j<=L;++j)
    h[c][u][j]=(h[c][son[u][0]][j]*(ll)cnt1+h[c][son[u][1]][j]*(ll)cnt0)%mod;
    }
    else {
    for(int j=1;j<=sz[son[u][0]];++j)
    for(int k=1;k<=sz[son[u][1]];++k)
    h[c][u][j+k]=(h[c][u][j+k]+h[c][son[u][0]][j]*(ll)h[c][son[u][1]][k])%mod;
    }
    }
    }
    int K,fp[N];
    int main() {
    freopen("nash.in","r",stdin);
    freopen("nash.out","w",stdout);
    rd(n),rd(K);
    for(int i=2;i<=n;++i) {
    rd(fa[i]); ++fa[i];
    (son[fa[i]][0]?son[fa[i]][1]:son[fa[i]][0])=i;
    dep[i]=dep[fa[i]]^1;
    }
    for(int i=1;i<=n;++i) L+=!son[i][0];
    for(int i=1;i<=n;++i)
    for(int j=1;j<=K;++j)
    fp[i]=(fp[i]+Pow(j,i-1))%mod;
    dfs(1);
    // cerr<<"ok"<<endl;
    int t1=0,t2=0;
    for(int i=1;i<=L;++i) {
    t1=(t1+h[0][1][i]*(ll)fp[i]%mod*(ll)Pow(K,mod-1-i))%mod;
    t2=(t2+h[1][1][i]*(ll)fp[i]%mod*(ll)Pow(K,mod-1-i))%mod;
    }
    int ans=t1*(ll)t2%mod*Pow(K,2*L)%mod;
    // int ans=0;
    // for(int i=1;i<=L;++i)
    // for(int j=1;j<=L;++j)
    // ans=(ans+h[0][1][i]*(ll)h[1][1][j]%mod*fp[i]%mod*fp[j]%mod*Pow(K,2*L-i-j)%mod)%mod;
    printf("%d",ans);
    return 0;
    }

最新文章

  1. &quot;Chinese_PRC_CI_AS&quot; 和 &quot;Chinese_PRC_90_CI_AI&quot; 之间的排序规则冲突问题
  2. [翻译]Java日志终极指南
  3. HTML 5表单应用小结
  4. Hibernate 和 快照
  5. 李洪强iOS经典面试题133--UNIX常用命令
  6. Django常用命令及参数配置(Django 1.8.6)
  7. WebGIS的大众化服务
  8. Net Core-Razor
  9. Web Reference for a WCF Service has Extra “IdSpecified” Parameter ?
  10. 转账示例(四):service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)
  11. bzoj 4819: [Sdoi2017]新生舞会
  12. 关于webService发布的wsdl中的import问题解决
  13. Java的访问权限详解(3+1)public private protected default
  14. js 批量替换
  15. allure --version 异常io.airlift.airline.ParseArgumentsUnexpectedException: Found unexpected parameter
  16. MySQL C API概述
  17. File 文件
  18. PHP pthread 多线程 案例
  19. localStorage 存满了怎么办?
  20. git命令行clone指定分支、更新、冲突解决、提交代码步骤

热门文章

  1. VMware学习笔记之在虚拟机中使用Ghost系统盘安装xp黑屏卡在光标闪无法进入系统
  2. navicat连接mysql出现2059
  3. webpack4引入JQuery的两种方法
  4. js获取列表多条数据(接口)
  5. Java 之 Response 对象
  6. JAVA导出excel 直接弹出下载框
  7. 1.live555源码分析----RSTPServer创建过程分析
  8. ugui用户定义操作按键
  9. 非Java程序员转行Java-day01-入门基础
  10. 尚学堂JAVA基础学习笔记