[NOIP2018模拟赛] 小P的Civilization V

题目链接、

题目描述:

小P最近在玩Civilization V,游戏的地图是一棵树,树的每个节点都可以当作战场,刚开始每个节点的战斗加成为0

现在小P拥有两种人员:

一种是工人,每个工人会有一个起点u和终点v,工人可以使u−>v路径上每个节点的战斗加成+1

一种是骑兵,每个战士也有一个起点u和终点v,战士可以选择u−>v路径上任意节点战斗

现有m个工人和q个骑兵,问每个骑兵作战最多可以拥有多少战斗加成

输入格式:

第一行三个整数n,m,q

接下来一行n−1个数,第i个数fi​​表示第i+1个节点的父亲

接下来m行,每行两个整数u,v,表示一个工人

接下来q行,每行两个整数u,v,表示一个骑兵

输出格式

q行,对于每个骑兵,输出他作战最多可以拥有多少战斗加成

样例

样例输入1

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

样例输出1

3
5
3
5
5

样例输入2

9 5 5
1 2 2 4 5 3 4 6 
4 9
4 7
1 7
1 2
2 1
9 9
9 9
3 3
7 7
2 2

样例输出2

1
1
2
2
4

对于15%的数据,保证n,q≤1000

对于另外15%的数据,保证fi​​=i

对于另外10%的数据,保证所有u=v

对于另外10%的数据,保证工人的u=v

对于另外10%的数据,保证骑兵的u=v

对于100%的数据,保证n,q≤500,000且fi≤i

早就想写这个题的博客了,为啥一直没写呢,在找zkw线段树的板子,一直找不到有解释清楚的(对于我来说,大佬的解释看不懂qew),(对了,关于那个ppt,里面代码是错的,就这样还有人把代码完完整整的抄下来,然后贴出来了,还tm好几千访问量,下面也没有说错的,我比着那代码都写自闭了)

终于在御坂美琴o((≧▽≦o) ╮( ̄▽ ̄")╭找到了能看懂的

 

嗯,找zkw线段树的原因是因为我的线段树t了,但是某人的线段树加inline卡常过去了

这题正解应该是线段树维护区间之后st表预处理,但是,既然zkw线段树能过为啥不去学一下呢

树剖不不多讲了,就是个板子,了解的话去,这里

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e5+7;
int read(){int c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
//链式前向星
int head[maxn],to[maxn<<1],nex[maxn<<1],cnt = 1,n,m,q;
void add(int u,int v){to[cnt] = v,nex[cnt] = head[u],head[u] = cnt++;}
//链式前向星
int son[maxn],id[maxn],fa[maxn],tot,dep[maxn],siz[maxn],top[maxn];
int A[maxn],N;
int tree[maxn<<2];
void push_up(int x,ll Mx = 0){
    Mx = max(tree[x],tree[x^1]);
    tree[x] -= Mx,tree[x^1] -= Mx;
    tree[x>>1] += Mx;
}
void build(int n){
	for(N=1;N<n+2;N<<=1);
	//for(int i=1;i<=n;++i) tree[N+i]=A[i];
	//for(int i=N-1;i;--i)tree[i] = max(tree[i<<1],tree[i<<1|1]);
	//for(int i=N+n;i;i--)tree[i] -= tree[i>>1];
}
void update(int s,int t,ll C){
	for(s=N+s-1,t=N+t+1;s^t^1;s>>=1,t>>=1){
		if(~s&1) tree[s^1]+=C;
		if( t&1) tree[t^1]+=C;
		push_up(s),push_up(t);
	}
	while(s>1)push_up(s),s>>=1;
}
int query(int s,int t,int Lans = 0,int Rans = 0){
    s += N,t += N;
    if(s != t){
        for(;s^t^1;s>>=1,t>>=1){
            Lans += tree[s];
            Rans += tree[t];
            if(~s&1) Lans = max(Lans,tree[s^1]);
            if( t&1) Rans = max(Rans,tree[t^1]);
        }
    }
	int ans = max(Lans+tree[s],Rans+tree[t]);
	while(s>1) ans += tree[s>>=1];
	return ans;
}
void dfs1(int u,int Fa,int deep){
    dep[u] = deep,fa[u] = Fa,siz[u] = 1;
    int maxnson = -1;
    for(int i=head[u];i;i=nex[i]){
        int y = to[i];
        if(y == Fa)continue;
        dfs1(y,u,deep+1);
        siz[u] += siz[y];
        if(siz[y] > maxnson)
            son[u] = to[i],maxnson = siz[y];
    }
}
void dfs2(int u,int tp){
    id[u] = ++tot;
    top[u] = tp;
    if(!son[u])return;
    dfs2(son[u],tp);
    for(int i=head[u];i;i=nex[i]){
        if(to[i] == fa[u] || to[i] == son[u])continue;
        dfs2(to[i],to[i]);//轻儿子有自己的想法
    }
}
void upRange(int x,int y,int val){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        update(id[top[x]],id[x],val);
        x = fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    update(id[x],id[y],val);
}
int qRange(int x,int y,int ans = 0){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        ans = max(ans,query(id[top[x]],id[x]));
        x = fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    return max(ans,query(id[x],id[y]));
}
int main(){
    //freopen("CV.in","r",stdin);
    //freopen("CV.out","w",stdout);
    n = read,m = read,q = read;
    for(int i=1,u;i<=n-1;i++){
        u = read;
        add(u,i+1),add(i+1,u);
    }
    dfs1(1,0,1);
    dfs2(1,1);
    build(n);
    while(m--){
        int u,v;
        u = read,v = read;
        upRange(u,v,1);
    }
    while(q--){
        int u,v;
        u = read,v = read;
        printf("%d\n",qRange(u,v));
    }
    return 0;
}

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值