【LOJ2537】Minimax(PKUWC2018)-树形DP+线段树合并

本文介绍了一种解决特定类型问题的方法,利用树形动态规划(树形DP)结合线段树合并技术。这种方法可以高效地处理涉及树状结构及区间操作的问题,并通过一个具体的例子详细阐述了实现过程。

测试地址:Minimax
做法:本题需要用到树形DP+线段树合并。
很快想到一种定义状态的方式: f(i,j) f ( i , j ) 表示点 i i 的权值为j(离散化后)的概率,然后转移时,因为这是棵二叉树,令 son s o n 为当前枚举的儿子, sum(j) s u m ( j ) 为另一个儿子中权值小于 j j 的概率,我们有以下状态转移方程:
f(i,j)=sonj=1nf(son,j)[pisum(j)+(1pi)(1sum(j))]
因为题目中说明了叶子节点权值各不相同,所以不用考虑重复的问题。那么我们就可以这样转移,时间复杂度为 O(n2) O ( n 2 )
然而显然过不了,这怎么办呢?我们发现,上面的转移过程就是把两个序列拼在一起,然后再进行某些区间乘就是新的概率。我们知道求区间和和维护区间乘可以用线段树维护,那么这个“序列合并”的操作显然就可以用线段树合并来维护了,因为区间乘操作只会出现在两棵树中仅在一棵中存在的子树中,所以直接在线段树合并时打标记即可。于是我们就完成了这一题,时间复杂度为 O(nlogn) O ( n log ⁡ n )
以下是本人代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
int n,first[300010]={0},tot=0,totp=0,rt[300010]={0},ch[6000010][2]={0};
ll p[6000010],seg[6000010]={0},tag[6000010]={0};
ll pxL,pyL,ans;
struct edge
{
    int v,next;
}e[300010];
struct forsort
{
    int id;
    ll val;
}f[300010];

bool cmp(forsort a,forsort b)
{
    return a.val<b.val;
}

void insert(int a,int b)
{
    e[++tot].v=b;
    e[tot].next=first[a];
    first[a]=tot;
}

ll power(ll a,ll b)
{
    ll s=1,ss=a;
    while(b)
    {
        if (b&1) s=s*ss%mod;
        ss=ss*ss%mod;b>>=1;
    }
    return s;
}

void update(int x,ll p)
{
    seg[x]=seg[x]*p%mod;
    tag[x]=tag[x]*p%mod;
}

void pushdown(int no)
{
    if (tag[no]!=1)
    {
        if (ch[no][0]) update(ch[no][0],tag[no]);
        if (ch[no][1]) update(ch[no][1],tag[no]);
        tag[no]=1;
    }
}

void pushup(int no)
{
    seg[no]=(seg[ch[no][0]]+seg[ch[no][1]])%mod;
}

void seginsert(int &no,int l,int r,int x)
{
    if (!no) no=++totp;
    tag[no]=1;
    if (l==r) {seg[no]=1;return;}
    int mid=(l+r)>>1;
    if (x<=mid) seginsert(ch[no][0],l,mid,x);
    else seginsert(ch[no][1],mid+1,r,x);
    pushup(no);
}

int merge(int x,int y,ll p)
{
    if (!x)
    {
        if (!y) return y;
        pyL=(pyL+seg[y])%mod;
        update(y,(p*pxL%mod+(1-p+mod)*(1-pxL+mod)%mod)%mod);
        return y;
    }
    if (!y)
    {
        pxL=(pxL+seg[x])%mod;
        update(x,(p*pyL%mod+(1-p+mod)*(1-pyL+mod)%mod)%mod);
        return x;
    }
    pushdown(x),pushdown(y);
    ch[x][0]=merge(ch[x][0],ch[y][0],p);
    ch[x][1]=merge(ch[x][1],ch[y][1],p);
    pushup(x);
    return x;
}

void solve(int v)
{
    int lson=0,rson=0;
    if (first[v])
    {
        lson=e[first[v]].v;
        solve(lson);
    }
    if (e[first[v]].next)
    {
        rson=e[e[first[v]].next].v;
        solve(rson);
    }
    if (!lson) return;
    if (!rson) rt[v]=rt[lson];
    else
    {
        pxL=pyL=0;
        rt[v]=merge(rt[lson],rt[rson],p[v]);
    }
}

void query(int no,int l,int r)
{
    if (l==r)
    {
        ans=(ans+(ll)l*f[l].val%mod*seg[no]%mod*seg[no]%mod)%mod;
        return;
    }
    int mid=(l+r)>>1;
    pushdown(no);
    query(ch[no][0],l,mid);
    query(ch[no][1],mid+1,r);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        if (x) insert(x,i);
    }

    tot=0;
    ll inv=power(10000,mod-2);
    for(int i=1;i<=n;i++)
    {
        if (!first[i])
        {
            scanf("%lld",&f[++tot].val);
            f[tot].id=i;
        }
        else
        {
            scanf("%lld",&p[i]); 
            p[i]=p[i]*inv%mod;
        }
    }
    sort(f+1,f+tot+1,cmp);
    for(int i=1;i<=tot;i++)
    {
        rt[f[i].id]=++totp;
        seginsert(rt[f[i].id],1,tot,i);
    } 

    solve(1);
    ans=0;
    query(rt[1],1,tot);
    printf("%lld",ans);

    return 0;
}
<think>嗯,用户遇到了两个问题:一个是Vue CLI中的defineConfig is not a function错误,另一个是npm提示的164 packages are looking for funding。我需要结合之前的对话和用户提供的引用内容来解答。首先,用户之前已经得到了一些解决方案,现在他们可能遇到了新的情况或者需要更详细的解释。 关于defineConfig的问题,之前的回答提到了升级@vue/cli-service、显式引入defineConfig、降级配置写法等方法。用户现在再次提到这个问题,可能需要确认是否遗漏了某些步骤,或者是否有其他原因导致错误依然存在。比如,用户可能没有正确升级依赖,或者配置文件中仍然没有正确引入defineConfig。另外,引用[2]中用户自己封装的npm组件配置可能涉及到vue.config.js的修改,比如修改入口文件路径或webpack配置,这可能引发其他问题,需要检查语法是否正确。 然后是npm fund的问题。引用[3]提到npm fund是开发者寻求捐赠的提示,可以通过添加--no-fund参数来跳过。用户可能想知道这些提示是否影响项目运行,以及如何处理。需要解释npm fund的作用,并给出具体的命令来禁用这些提示。 用户现在同时问这两个问题,需要分别解答,但也要注意两者是否有潜在联系。例如,升级npm包时可能会触发更多的funding提示,或者用户在处理错误时运行了npm install,从而看到了这些提示。需要确认用户是否在解决defineConfig错误的过程中遇到了npm fund的提示,因此需要分别处理。 另外,用户提供的引用[1]提到安装Node.js和npm是使用Vue CLI的前提,但用户已经遇到了配置问题,可能已经正确安装了环境,所以当前问题更多是配置和依赖管理的问题,而非环境准备。 需要检查用户是否按照步骤升级了@vue/cli-service,是否正确修改了vue.config.js文件,是否有残留的node_modules或lock文件导致版本不一致。同时,关于npm fund,需要明确告知用户这是无害的提示,并提供禁用方法。 可能用户还希望了解funding提示的意义,是否会影响项目安全或功能,需要解释这是开源维护者寻求支持的方式,不影响代码执行,但用户可以选择支持或忽略。 最后,确保回答结构清晰,分点解答,每个问题有对应的解决方案,并参考之前的引用内容,但以用户当前的问题为主。</think>### 分步解决方案:`defineConfig is not a function` 与 `npm fund` 警告 --- ### **第一部分:解决 `defineConfig is not a function` 错误** #### **1. 根本原因分析** 该错误表明 `vue.config.js` 中使用的 `defineConfig` 函数未被正确加载,通常由以下原因导致: - **原因1**:`@vue/cli-service` 版本过低(Vue CLI 4.5 以下不支持此语法)[^1] - **原因2**:未显式引入 `defineConfig` 函数 - **原因3**:项目依赖未完全清理或存在缓存冲突 --- #### **2. 具体解决步骤** **步骤1:升级 Vue CLI 依赖** 确保 `@vue/cli-service` 版本≥4.5.15 或使用 5.x 版本: ```bash # 检查当前版本 npm list @vue/cli-service # 升级到最新版本 npm update @vue/cli-service@latest ``` **步骤2:显式引入 `defineConfig`** 在 `vue.config.js` 中直接声明依赖: ```javascript const { defineConfig } = require('@vue/cli-service'); // 关键引入 module.exports = defineConfig({ transpileDependencies: true, // 其他配置... }); ``` **步骤3:降级配置写法(兼容旧版本)** 如果升级失败或需兼容旧项目,改用传统导出方式: ```javascript // vue.config.js module.exports = { pages: { index: { entry: 'examples/main.js' } }, // 如引用[2]中的自定义入口 css: { extract: false }, chainWebpack: (config) => { /* 自定义 webpack 配置 */ } }; ``` **步骤4:清理依赖缓存** 删除 `node_modules` 和 `package-lock.json`(或 `yarn.lock`),重新安装依赖: ```bash rm -rf node_modules package-lock.json npm install ``` --- ### **第二部分:理解 `164 packages are looking for funding` 警告** #### **1. 含义解析** - **`npm fund` 提示**:表示安装的依赖包中有 164 个开源项目在寻求资金支持。 - **本质**:开源维护者通过此功能声明捐赠渠道(如 GitHub Sponsors、Patreon 等),与代码功能无关,仅为信息提示[^3]。 #### **2. 处理方法** **方法1:关闭警告** 在运行 `npm` 命令时添加 `--no-fund` 参数: ```bash npm install --no-fund # 安装时跳过提示 npm run dev --no-fund # 运行时跳过提示 ``` **方法2:永久禁用** 在 `.npmrc` 配置文件中全局关闭: ```bash echo "fund=false" >> ~/.npmrc # 对所有项目生效 ``` **方法3:查看具体信息** 若想了解哪些包需要支持,可运行: ```bash npm fund ``` --- ### **关联问题与场景** #### **1. 自定义组件库配置问题(引用[2])** 若在封装组件库时修改了 `vue.config.js` 的入口路径(如 `pages.index.entry`),需注意: - 确保 `examples/main.js` 文件路径正确 - `chainWebpack` 配置需符合 Vue CLI 的语法规则(避免语法错误导致 `defineConfig` 加载失败) #### **2. 依赖版本冲突** 若升级 `@vue/cli-service` 后出现其他依赖冲突,可通过以下命令修复: ```bash npm install --force # 强制重新安装所有依赖 ``` --- ### **总结表格** | 问题类型 | 关键操作 | 验证方式 | |--------------------------|----------------------------------------|----------------------------------| | `defineConfig` 未定义 | 升级 `@vue/cli-service` + 显式引入 | 检查配置文件语法和版本号 | | `npm fund` 资金提示 | 使用 `--no-fund` 或修改 `.npmrc` | 观察终端警告是否消失 | | 自定义入口配置错误 | 检查 `pages.index.entry` 路径 | 运行 `npm run serve` 是否报错 | --- ### **扩展问题** 1. 如何区分 Vue CLI 和 Vite 的 `defineConfig` 语法? 2. `transpileDependencies: true` 在 `vue.config.js` 中的作用是什么? 3. 开源项目的 `npm fund` 资金支持是否影响代码安全性? --- **附:快速修复命令清单** ```bash # 修复 defineConfig 错误 npm update @vue/cli-service@latest --force rm -rf node_modules package-lock.json npm install --no-fund # 关闭资金提示(永久) echo "fund=false" >> ~/.npmrc ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值