阴阳

题目大意

给定一颗有n个结点的树,每条边的权值为1或-1。问有多少点对(i,j)(注意点对不存在顺序性),满足i到j的最短路径上能找到一个点k,使得i到k的最短路径权值和为0,k到j的最短路径权值和为0。
n<=100000。

点分治

我们进行点分治。
对于当前的根x,我们统计有多少对经过了x的满足题目要求。
我们可以处理出d[i]表示i到x的权值和,b[i]=1表示i到x路径上可以找到异与i与x的一点k满足d[k]=d[i]。
注意到如果i与j是合法的,d[i]+d[j]=0。
因此我们可以用桶进行统计。
所有b[i]=1且d[i]=0的点都可以与x凑成“合法”点对。
所有d[i]=0的点都可以成为“合法”点对。
注意可能会有出自同一子树的点对满足条件,因此分治下去是减去非法方案。

参考程序

#include<cstdio>
#include<algorithm>
#include<deque>
#include<stack>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const ll maxn=100000*2+10;
deque<ll> dl;
stack<ll> sta;
ll a[maxn],sum[maxn],d[maxn],h[maxn],go[maxn],next[maxn],dis[maxn],s[maxn],pd[maxn],fa[maxn],fi[maxn];
bool b[maxn],bz[maxn],vis[maxn],czy;
ll i,j,k,l,t,n,m,tot,top,ans;
void add(ll x,ll y,ll z){
    go[++tot]=y;
    dis[tot]=z;
    next[tot]=h[x];
    h[x]=tot;
}
void dg(ll x){
    dl.push_back(x);
    vis[x]=1;
    a[top=1]=x;
    ll now,t;
    while (!dl.empty()){
        t=h[now=dl.front()];
        sta.push(now);
        s[now]=1;
        dl.pop_front();
        while (t){
            if (!bz[go[t]]&&!vis[go[t]]){
                vis[go[t]]=1;
                a[++top]=go[t];
                fa[go[t]]=now;
                dl.push_back(go[t]);
            }
            t=next[t];
        }
    }
    while (!sta.empty()){
        s[fa[sta.top()]]+=s[sta.top()];
        sta.pop();
    }
}
void dfs(ll x){
    ll i,now;
    fo(i,1,top) fi[a[i]]=h[a[i]];
    sta.push(x);
    vis[x]=1;
    while (!sta.empty()){
        now=sta.top();
        while (fi[now]&&(vis[go[fi[now]]]||bz[go[fi[now]]])) fi[now]=next[fi[now]];
        if (!fi[now]){
            sta.pop();
            if (!sta.empty())pd[d[now]]--;
            continue;
        }
        vis[go[fi[now]]]=1;
        d[go[fi[now]]]=d[now]+dis[fi[now]];
        b[go[fi[now]]]=0;
        if (pd[d[go[fi[now]]]]) b[go[fi[now]]]=1;
        pd[d[go[fi[now]]]]++;
        sta.push(go[fi[now]]);
    }
}
void count(ll sig){
    ll i;
    fo(i,1,top) 
        if (b[a[i]]&&d[a[i]]>0) sum[d[a[i]]]++;
    fo(i,1,top)
        if (d[a[i]]<0) ans=ans+sig*sum[-d[a[i]]];
    fo(i,1,top){
        if (b[a[i]]&&d[a[i]]>0) sum[d[a[i]]]--;
        if (b[a[i]]&&d[a[i]]<0) sum[-d[a[i]]]++;
    }
    fo(i,1,top)
        if (!b[a[i]]&&d[a[i]]>0) ans=ans+sig*sum[d[a[i]]];
    fo(i,1,top)
        if (b[a[i]]&&d[a[i]]<0) sum[-d[a[i]]]--;
    ll cnt=0;
    fo(i,1,top) 
        if (!d[a[i]]) cnt++;
    if (cnt){
        if (sig==1) cnt--;
        ans=ans+sig*cnt*(cnt-1)/2;
    }
}
void solve(ll x){
    top=0;
    dg(x);
    ll i,j=x,k=0,t;
    fo(i,1,top) vis[a[i]]=0;
    if (czy) count(-1);else czy=1;
    while (1){
        t=h[j];
        while (t){
            if (!bz[go[t]]&&go[t]!=k&&s[go[t]]>s[x]/2){
                k=j;
                j=go[t];
                break;
            }
            t=next[t];
        }
        if (!t) break;
    }
    d[j]=0;
    b[j]=0;
    dfs(j);
    fo(i,1,top) vis[a[i]]=0;
    count(1);
    fo(i,1,top)
        if (!d[a[i]]&&b[a[i]]) ans++;
    t=h[j];
    bz[j]=1;
    //printf("%lld %lld %lld\n",x,j,ans);
    while (t){
        if (!bz[go[t]]) solve(go[t]);
        t=next[t];
    }
}
int main(){
    //freopen("D:/in.txt","r",stdin);
    scanf("%lld",&n);
    fo(i,1,n-1){
        scanf("%lld%lld%lld",&j,&k,&t);
        if (!t) t=-1;
        add(j,k,t);
        add(k,j,t);
    }
    //printf("\n");
    solve(1);
    //printf("\n");
    printf("%lld\n",ans);
}
<think>好的,我现在需要处理用户关于《阴阳师》游戏的查询,用户的问题包括游戏介绍、下载方式和策略攻略。首先,我要确认每个部分的信息是否准确,并且按照用户的要求来组织回答结构。 关于游戏介绍部分,我需要确认游戏的背景设定、主要玩法和特色。记得提到和风美术和声优阵容,这些都是阴阳师的重要卖点。可能还需要提到游戏的主要模式,比如剧情任务、式神收集和PVP/PVE内容。 下载方式方面,用户可能需要不同平台的步骤,比如iOS和Android,以及官方渠道的重要性。需要确保下载链接是官方的,避免第三方平台的风险。还要提醒注意账号安全和版本更新。 策略攻略部分需要涵盖式神培养、御魂搭配、阵容组合和活动参与。这部分需要具体且实用,比如推荐哪些SSR式神,御魂的属性选择,阵容搭配的例子,以及如何高效参与活动。可能需要参考最新的攻略,确保信息不过时。 接下来要考虑用户的格式要求:分点回答,避免使用步骤词汇,每个部分换行。同时,数学公式和代码部分可能不适用,但如果有数值计算或阵容代码示例,需要正确使用格式。不过目前看起来攻略部分不需要代码,可能不需要处理。 最后,生成相关问题时要基于用户的问题和回答内容。比如,用户可能对式神强度、资源管理或最新活动感兴趣,所以相关问题需要围绕这些方面展开。确保三个问题,用数字列表,标题正确,没有多余的空格或换行。 现在需要检查是否所有要求都被满足:没有第一人称,没有步骤词汇,引用分散,分方法或步骤,换行分隔,相关问题正确格式。确保每个部分清晰,信息准确,并且符合用户的具体需求。</think>《阴阳师》是由网易研发的3D日式和风回合制RPG手游,以日本平安时代为背景,结合妖怪文化与阴阳师职业设定。玩家扮演阴阳师,通过收集式神、探索剧情、参与战斗和社交互动展开游戏。以下是详细信息: --- **游戏介绍** - **核心玩法**:以回合制战斗为主,包含PVE剧情副本、御魂副本、探索关卡及PVP斗技场。 - **式神系统**:角色分为SSR/SP/SR/R/N等级,需通过召唤或碎片合成获取,部分式神具备独特技能机制(如鬼切、不知火)。 - **美术与声优**:采用和风美术设计,角色立绘与场景细腻;配音阵容包括钉宫理惠、杉山纪彰等日本一线声优。 - **社交功能**:支持创建阴阳寮(公会)、组队刷副本、结界突破等互动玩法。 --- **下载方式** - **iOS用户**:App Store搜索“阴阳师”,选择网易官方版本下载(需日区/国区账号)。 - **Android用户**:官网(https://yys.163.com)或TapTap平台下载安装包,注意开启“允许未知来源安装”。 - **PC端**:官网提供桌面版客户端,支持多开与键鼠操作优化。 --- **策略攻略** **式神培养优先级** 初期推荐培养群体输出式神(如大天狗、玉藻前)和辅助(如座敷童子、山兔)。SSR式神如阿修罗、千姬在当前版本强度较高。 **御魂搭配** 输出式神常用“破势”“针女”四件套,主属性选择攻击/暴击: $$攻击力 = 基础攻击 \times (1 + 御魂加成) + 固定攻击$$ 辅助式神优先“招财猫”“火灵”,速度属性需达到128+以抢回合先手。 **阵容组合** 通用PVE阵容:输出+打火机(供火)+拉条(加速)+治疗+控制。 示例代码计算伤害(Python): ```python def damage_cal(base_attack, crit_damage, skill_multiplier): return base_attack * crit_damage * skill_multiplier print(damage_cal(8000, 2.5, 3.2)) # 输出64000 ``` **活动参与技巧** 限时活动(如“超鬼王”“伪神降临”)需提前囤积体力与资源,优先兑换SSR/SP召唤券、黑蛋等高价值道具。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值