Description

题目背景:
尊者神高达很穷,所以他需要跑商来赚钱
题目描述:
基三的地图可以看做 n 个城市,m 条边的无向图,尊者神高达会从任意一个点出发并在起点购买货物,在旅途中任意一点卖出并最终到达终点,尊者神高达的时间很宝贵,所以他不会重复经过同一个城市,但是为了挣钱,他可能会去绕路。当然,由于工作室泛滥,所以一个城市的货物价格可能会发生改变。但是尊者神高达智商不足,他可能在一个很蠢的节点把货物卖掉,所以尊者神高达想知道每一次跑商最多能赔多少钱。

Input

第一行 n,m;
接下来 1 行 n 个数,代表每个城市货物的价格;
接下来 m 行 u,v 代表一条边
接下来 1 行 Q
接下来 Q 行
C x w 代表城市 x 的货物价格变为 w
Q u v 代表一次从 u 到 v 的跑商

Output

如题目描述

Sample Input

3 3
1 2 3
1 2
2 3
1 3
3
Q 2 3
C 1 5
Q 1 3

Sample Output

1
3

样例解释:
1,2,3 都联通,起点购买价格为 2,在 1 点卖出赔得最多2-1=1
更新后每个点价值为 5,2,3
起点价格为 5,在 2 点卖出赔得最多,5-2=3

Data Constraint

40%的数据为一棵树
另外 20%的数据没有修改操作
所以数据满足 n,m,q<=100000;保证图联通,数据合法

Solution

  • 40%的数据就是裸的树链剖分,查询区间最小值、单点修改即可。

  • 而变成无向图后呢,就要用到圆方树了!

  • 圆方树是处理仙人掌的利器,应用广泛。

  • 嗯,首先,它是一棵树,由圆点和方点组成。

  • 原图中就存在的点被称为圆点,我们将其缩点双联通分量后,新建一个方点来代表这个点双,

  • 并将点双中的点与这个方点连边(原来点双里面的边就不要了),缩点双用 tarjan 算法。

  • 建出来的圆方树的圆点和方点是相隔的,即不会有圆点连圆点、方点连方点。

  • 有了这颗圆方树,我们就能解决很多问题了!

  • 在本题中,圆点的权值就设为其本来的值(即 aia_iai​),而方点的值就是点双中点权的最小值。

  • 注意: 这里方点的值不包括其父亲圆点的(这样好算很多)。

  • 于是查询就能用树链剖分求最小值了,注意若两点lca是方点,还得算上其父亲圆点的值。

  • 而查询的话,对于该圆点就单点修改,对于其属于的方点就用一个set(可维护插入删除,求最小值的数据结构)维护其包含的圆点值即可。

  • 时间复杂度 O(nlog2n)O(n\ log^2n)O(n log2n) 。

Code

#include<cstdio>
#include<algorithm>
#include<set>
#include<cctype>
using namespace std;
const int N=1e5+5,inf=1e9;
int n,m,tot=1,num,cnt,rt,qx,qy,stop,ans;
int first[N],nex[N<<1],en[N<<1];
int first1[N<<1],nex1[N<<1],en1[N<<1],d[N<<1];
int a[N];
int dfn[N],low[N],st[N],id[N];
int fa[N<<1],dep[N<<1],size[N<<1],son[N<<1];
int top[N<<1],tree[N<<1],pre[N<<1],f[N<<3];
multiset<int>ss[N<<1];
multiset<int>::iterator it;
inline int read()
{int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<1)+(X<<3)+(ch^48),ch=getchar();return w?-X:X;
}
inline void insert(int x,int y)
{nex[++tot]=first[x];first[x]=tot;en[tot]=y;
}
inline void insert1(int x,int y)
{nex1[++tot]=first1[x];first1[x]=tot;en1[tot]=y;d[y]++;
}
inline int min(int x,int y)
{return x<y?x:y;
}
void tarjan(int x,int y)
{dfn[x]=low[x]=++num;st[++stop]=x;for(int i=first[x];i;i=nex[i])if(!dfn[en[i]]){tarjan(en[i],i^1);low[x]=min(low[x],low[en[i]]);if(low[en[i]]>=dfn[x]){cnt++;do{id[st[stop]]=cnt;insert1(cnt,st[stop]);ss[cnt].insert(a[st[stop]]);}while(st[stop--]^en[i]);insert1(x,cnt);}}elseif(i^y) low[x]=min(low[x],dfn[en[i]]);
}
void dfs(int x)
{dep[x]=dep[fa[x]]+1;size[x]=1;for(int i=first1[x];i;i=nex1[i])if(en1[i]^fa[x]){fa[en1[i]]=x;dfs(en1[i]);size[x]+=size[en1[i]];if(!son[x] || size[son[x]]<size[en1[i]]) son[x]=en1[i];}
}
void dfs1(int x,int y)
{top[pre[tree[x]=++num]=x]=y;if(!son[x]) return;dfs1(son[x],y);for(int i=first1[x];i;i=nex1[i])if(en1[i]^fa[x] && en1[i]^son[x]) dfs1(en1[i],en1[i]);
}
void make(int v,int l,int r)
{if(l==r){if(pre[l]>n){it=ss[pre[l]].begin();f[v]=*it;}else f[v]=a[pre[l]];return;}int mid=l+r>>1;make(v<<1,l,mid);make(v<<1|1,mid+1,r);f[v]=min(f[v<<1],f[v<<1|1]);
}
int find(int v,int l,int r)
{if(qx<=l && r<=qy) return f[v];int mid=l+r>>1;int s=inf;if(qx<=mid) s=find(v<<1,l,mid);if(qy>mid) s=min(s,find(v<<1|1,mid+1,r));return s;
}
void change(int v,int l,int r)
{if(l==r){f[v]=qy;return;}int mid=l+r>>1;if(qx<=mid) change(v<<1,l,mid); else change(v<<1|1,mid+1,r);f[v]=min(f[v<<1],f[v<<1|1]);
}
int main()
{freopen("paoshang.in","r",stdin);freopen("paoshang.out","w",stdout);n=cnt=read(),m=read();for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<=m;i++){int x=read(),y=read();insert(x,y);insert(y,x);}tarjan(1,tot=0);for(int i=1;i<=cnt;i++)if(!d[i]){rt=i;break;}dfs(rt);num=0;dfs1(rt,rt);make(1,1,num);int q=read();while(q--){char ch=getchar();while(ch^'Q' && ch^'C') ch=getchar();if(ch=='Q'){int x=read(),y=read(),st=a[x];ans=inf;int f1=top[x],f2=top[y];while(f1^f2){if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);qx=tree[f1],qy=tree[x];ans=min(ans,find(1,1,num));x=fa[f1],f1=top[x];}if(dep[x]>dep[y]) swap(x,y);qx=tree[x],qy=tree[y];ans=min(ans,find(1,1,num));if(x>n) ans=min(ans,a[fa[x]]);printf("%d\n",st-ans);}else{int x=read(),w=read();qx=tree[x],qy=w;change(1,1,num);int y=id[x];if(y){it=ss[y].find(a[x]);ss[y].erase(it);ss[y].insert(w);it=ss[y].begin();qx=tree[y],qy=*it;change(1,1,num);}a[x]=w;}}return 0;
}

JZOJ 5909. 【NOIP2018模拟10.16】跑商(paoshang)相关推荐

  1. [JZOJ 5909] [NOIP2018模拟10.16] 跑商(paoshang) 解题报告 (圆方树)

    题目链接: https://jzoj.net/senior/#contest/show/2529/2 题目: 题目背景: 尊者神高达很穷,所以他需要跑商来赚钱 题目描述: 基三的地图可以看做 n 个城 ...

  2. 5909. 【NOIP2018模拟10.16】跑商(圆方树+树链剖分+SET)

    题目大意: 基三的地图可以看做 n 个城市,m 条边的无向图,尊者神高达会从任意一个点出发并在起点购买货物,在旅途中任意一点卖出并最终到达终点,尊者神高达的时间很宝贵,所以他不会重复经过同一个城市,但 ...

  3. jzoj5909 【NOIP2018模拟10.16】跑商(圆方树性质+树剖)

    Description 一个无向图,求从i到j简单路径(无重点)上的最小点权. n,m<=1e5 分析 考虑走到某个点双上时,假如不是同点进同点出,就可以获得这个点双上的所有贡献. 于是建出圆方 ...

  4. JZOJ 5907. 【NOIP2018模拟10.16】轻功(qinggong)

    Description 题目背景: 尊者神高达进入了基三的世界,作为一个 mmorpg 做任务是必不可少的,然而跑地图却令人十分不爽.好在基三可以使用轻功,但是尊者神高达有些手残,他决定用梅花桩练习轻 ...

  5. [JZOJ5909]【NOIP2018模拟10.16】跑商【圆方树】【树链剖分】

    Description 基三的地图可以看做 n 个城市,m 条边的无向图,尊者神高达会从某个点出发并在起点购买货物,在旅途中任意一点卖出并最终到达终点,尊者神高达的时间很宝贵,所以他不会重复经过同一个 ...

  6. [JZOJ 5911] [NOIP2018模拟10.18] Travel 解题报告 (期望+树形DP)

    题目链接: http://172.16.0.132/senior/#contest/show/2530/1 题目: EZ同学家里非常富有,但又极其的谦虚,说话又好听,是个不可多得的人才.       ...

  7. jzoj 5906. 【NOIP2018模拟10.15】传送门(树形dp)

    5906. [NOIP2018模拟10.15]传送门 Description 8102年,Normalgod在GLaDOS的帮助下,研制出了传送枪.但GLaDOS想把传送枪据为己有,于是把Normal ...

  8. jzoj5904. 【NOIP2018模拟10.15】刺客信条(并查集)

    5904. [NOIP2018模拟10.15]刺客信条 Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一 ...

  9. jzoj5920. 【NOIP2018模拟10.21】风筝(dp,最长上升子序列)

    5920. [NOIP2018模拟10.21]风筝 Description 当一阵风吹来,风筝飞上天空,为了你,而祈祷,而祝福,而感动-- Description oyiya 在 AK 了 IOI 之 ...

最新文章

  1. mysql服务在tcp6_为什么 netstat 对某些服务只显示了 tcp6 监听端口
  2. 进入编辑模式、vim命令模式、vim实践
  3. redis集群添加节点报错Either the node already knows other nodes (check with CLUSTER NODES) or contains some k
  4. java 反射 类名_java – 从反射中获取字段的类名
  5. WTL学习笔记——初章
  6. java高并发的经验
  7. 查找出/tmp目录下面修改时间是7天以前,大小在50k到2M之间,并以.log结尾的文件...
  8. 5分钟通过水痘事件来认识系统架构
  9. Autojs: 坚果云文本文件上传/下载
  10. iOS开发者程序许可协议
  11. UE4材质05 方向和法向
  12. 使用华为云服务器搭建一个简单网站(内容全面)
  13. 几何画板 linux,用几何画板怎么作函数图像
  14. ​[c/c++后台开发面经系列]4 Zoom面经(含答案)
  15. 线性反馈移位寄存器(LSFR)
  16. python建站有什么缺点_python有哪些建站系统?
  17. 5G手机决战中途岛:荣耀V30系列为行业划下基准线
  18. shopeeLazada菲律宾市场好做吗?东南亚菲律宾站点热卖产品5大类推荐
  19. 无线接入点和无线路由器有什么不同?
  20. 机器学习基础---回归方法---最小二乘回归

热门文章

  1. window下使用rtl-sdr和sdrsharp
  2. PyTorch进行神经风格转换/迁移(Neural-Transfer:图像风格迁移)
  3. Python学习笔记:常用第三方模块3
  4. php laravel 排序,php – 在laravel中排序数组
  5. 第18课:项目实战——利用 PyTorch 构建 RNN 模型
  6. Coursera吴恩达《神经网络与深度学习》课程笔记(4)-- 浅层神经网络
  7. 台湾大学林轩田机器学习技法课程学习笔记16(完结) -- Finale
  8. 关于面象接口编程的理解
  9. WINDOWS系统常用程序及快捷键
  10. “Imperceptible,Robust,and Targeted Adversaria lExamples for Automatic Speech Recognition”