G-Yu Ling(Ling YueZheng) and Colorful Tree

HOWARLI题解

大致做法就是首先考虑哪些修改可能影响询问,当修改点权是询问的倍数时才可能影响询问。于是考虑把他们放在一起。

首先每次枚举每种询问的倍数,把这些修改和当前询问放在一起,由于每次考虑的是该点到根节点路径上的点,对于每个点的点权的修改仅仅影响的子树节点的询问。于是将单点修改→\to→子树修改,链询问→\to→单点询问。

于是每次修改转化成[dfnu,dfnu+szu−1][\text{dfn}_u,\text{dfn}_u+\text{sz}_u-1][dfnu​,dfnu​+szu​−1]添加一个[x,disu][x,\text{dis}_u][x,disu​]即可以表示成插入{id,dfnu→dfnu+szu−1,x}=disu\{\text{id},\text{dfn}_u \to \text{dfn}_u+\text{sz}_u-1,x\} = \text{dis}_u{id,dfnu​→dfnu​+szu​−1,x}=disu​

于是询问的问题转化成dfnu\text{dfn}_udfnu​处询问[[l,r],max⁡{disu}][[l,r],\max\{\text{dis}_u\}][[l,r],max{disu​}]可以表示成询问max⁡{{id,dfnu,l→r}=dis}\max\{\{\text{id},\text{dfn}_u,l\to r\}=\text{dis}\}max{{id,dfnu​,l→r}=dis}

现在相当于有三维[id,dfn,val][\text{id},\text{dfn},\text{val}][id,dfn,val],即空间上的一个点,点权是dis\text{dis}dis,显然可以树套树或者cdq分治。

分析一下就可以知道上述求的max⁡dis\max \text{dis}maxdis一定是离uuu最近的。
下面代码用cdq分治。不过wtcl还没调出来~~

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
const int N=110005;
int h[N],e[2*N],ne[2*N],idx;
ll w[2*N];
void add(int a,int b,ll c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;}int n,m;
struct node1
{int op,u,x;int l,r;
}q[N];
struct node2
{int op,id;int t,l,r;ll x;
}q0[N<<1];
int dfn[N],timestamp;
ll dis[N];
int sz[N];
void dfs(int u,int fa)
{dfn[u]=++timestamp;sz[u]=1;for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa) continue;dis[v]=dis[u]+w[i];dfs(v,u);sz[u]+=sz[v];}
}
vector<int> V0[N],V1[N];
ll v[N<<2];
ll ans[N];
void modify(int u,int l,int r,int pos,ll x)
{if(l==r) return v[u]=x,void();int mid=l+r>>1;if(pos<=mid) modify(u<<1,l,mid,pos,x);else   modify(u<<1|1,mid+1,r,pos,x);v[u]=max(v[u<<1],v[u<<1|1]);
}
ll query(int u,int l,int r,int L,int R)
{if(L<=l&&r<=R) return v[u];int mid=l+r>>1;ll c=-1;if(L<=mid) c=max(c,query(u<<1,l,mid,L,R));if(R>mid)c=max(c,query(u<<1|1,mid+1,r,L,R));return c;
}
void solve(int l,int r)
{if(l>=r) return;int mid=l+r>>1;solve(l,mid),solve(mid+1,r);int i=l;for(int j=mid+1;j<=r;j++){while(i<=mid&&q0[i].t<=q0[j].t){if(q0[i].op==0) modify(1,1,n,q0[i].l,q0[i].x);i++;}if(q0[j].op==1) ans[q0[j].id]=max(ans[q0[j].id],query(1,1,n,q0[j].l,q0[j].r));}while(i>l) {--i;if(q0[i].op==0) modify(1,1,n,q0[i].l,-1);}inplace_merge(q0+l,q0+mid+1,q0+r+1,[](const node2&a,const node2&b){return a.t<b.t;});
}
int main()
{n=rd(),m=rd();memset(h,-1,sizeof h);memset(v,-1,sizeof v);memset(ans,-1,sizeof ans);for(int i=1;i<n;i++) {int u=rd(),v=rd(),c=rd();add(u,v,c),add(v,u,c);}for(int i=1;i<=m;i++){q[i].op=rd();q[i].u=rd();if(q[i].op) {q[i].l=rd(),q[i].r=rd(),q[i].x=rd();V1[q[i].x].push_back(i);}else {q[i].x=rd();V0[q[i].x].push_back(i);}}dfs(1,0);int cnt;for(int i=1;i<=n;i++){if(V1[i].empty()) continue;cnt=0;for(int j=i;j<=n;j+=i){for(int k:V0[j]){int u=q[k].u;q0[++cnt]={0,k,dfn[u],j,j,dis[u]};q0[++cnt]={0,k,dfn[u]+sz[u],j,j,-1};}}if(!cnt) continue;for(int k:V1[i]){int u=q[k].u,l=q[k].l,r=q[k].r;q0[++cnt]={1,k,dfn[u],l,r};}sort(q0+1,q0+1+cnt,[](const node2& a,const node2 &b){return a.id<b.id||a.id==b.id&&a.op<b.op;});solve(1,cnt);}for(int i=1;i<=m;i++){if(q[i].op==0) continue;if(ans[i]==-1)puts("Impossible!");elseprintf("%lld\n",dis[q[i].u]-ans[i]);}
}

上面代码有大问题

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
const int N=110005;
int h[N],e[2*N],ne[2*N],idx;
ll w[2*N];
void add(int a,int b,ll c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;}int n,m;
struct node1
{int op,u,x;int l,r;
}q[N];
struct node2
{int op,id;int t,l,r;ll x;
}q0[N<<1];
int dfn[N],timestamp;
ll dis[N];
int sz[N];
void dfs(int u,int fa)
{dfn[u]=++timestamp;sz[u]=1;for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa) continue;dis[v]=dis[u]+w[i];dfs(v,u);sz[u]+=sz[v];}
}
vector<int> V0[N],V1[N];
ll v[N<<2];
ll ans[N];
void modify(int u,int l,int r,int pos,ll x)
{if(l==r) return v[u]=x,void();int mid=l+r>>1;if(pos<=mid) modify(u<<1,l,mid,pos,x);else   modify(u<<1|1,mid+1,r,pos,x);v[u]=max(v[u<<1],v[u<<1|1]);
}
ll query(int u,int l,int r,int L,int R)
{if(L<=l&&r<=R) return v[u];int mid=l+r>>1;ll c=-1;if(L<=mid) c=max(c,query(u<<1,l,mid,L,R));if(R>mid)c=max(c,query(u<<1|1,mid+1,r,L,R));return c;
}struct node3
{int id;ll v;node3(){}node3(int id,ll v):id(id),v(v){}bool operator<(const node3&o)const{return v>o.v||v==o.v&&id<o.id;}
};
multiset<node3> mp[N];
multiset<node3>::iterator it;
void solve(int l,int r)
{if(l>=r) return;int mid=l+r>>1;solve(l,mid),solve(mid+1,r);int i=l;for(int j=mid+1;j<=r;j++){while(i<=mid&&q0[i].t<=q0[j].t){if(q0[i].op==0) {if(q0[i].x<0) {it=mp[q0[i].r].find(node3(q0[i].t-q0[i].l,-q0[i].x));if(it!=mp[q0[i].r].end()) mp[q0[i].r].erase(it);}elsemp[q0[i].r].insert(node3(q0[i].t,q0[i].x));if(mp[q0[i].r].size()) modify(1,1,n,q0[i].r,mp[q0[i].r].begin()->v);elsemodify(1,1,n,q0[i].r,-1);}i++;}if(q0[j].op==1) ans[q0[j].id]=max(ans[q0[j].id],query(1,1,n,q0[j].l,q0[j].r));}while(i>l) {--i;if(q0[i].op==0){modify(1,1,n,q0[i].r,-1);mp[q0[i].r].clear();}}inplace_merge(q0+l,q0+mid+1,q0+r+1,[](const node2&a,const node2&b){return a.t<b.t;});
}
int main()
{n=rd(),m=rd();memset(h,-1,sizeof h);memset(v,-1,sizeof v);memset(ans,-1,sizeof ans);for(int i=1;i<n;i++) {int u=rd(),v=rd(),c=rd();add(u,v,c),add(v,u,c);}for(int i=1;i<=m;i++){q[i].op=rd();q[i].u=rd();if(q[i].op) {q[i].l=rd(),q[i].r=rd(),q[i].x=rd();V1[q[i].x].push_back(i);}else {q[i].x=rd();V0[q[i].x].push_back(i);}}dis[1]=1;dfs(1,0);int cnt;for(int i=1;i<=n;i++){if(V1[i].empty()) continue;cnt=0;for(int j=i;j<=n;j+=i){for(int k:V0[j]){int u=q[k].u;q0[++cnt]={0,k,dfn[u],j,j,dis[u]};q0[++cnt]={0,k,dfn[u]+sz[u],sz[u],j,-dis[u]};}}for(int k:V1[i]){int u=q[k].u,l=q[k].l,r=q[k].r;q0[++cnt]={1,k,dfn[u],l,r};}sort(q0+1,q0+1+cnt,[](const node2& a,const node2 &b){return a.id<b.id||a.id==b.id&&a.t<b.t;});solve(1,cnt);}for(int i=1;i<=m;i++){if(q[i].op==0) continue;if(ans[i]==-1)puts("Impossible!");elseprintf("%lld\n",dis[q[i].u]-ans[i]);}
}

调了一天了,现在感觉这样写不太行www,cdq分治必须贡献能够分开计算,显然最大值不能贡献累加,导致上面写法可能不太行,草(一种植物)一天没了~

2021牛客暑期多校训练营3 G-Yu Ling(Ling YueZheng) and Colorful Tree(cdq分治)相关推荐

  1. 2021牛客暑期多校训练营1 G Game of Swapping Numbers 思维 + 巧妙的转换

    传送门 文章目录 题意: 思路: 题意: 给你两个数组A,BA,BA,B,你可以选择AAA的两个位置i,j,i<ji,j,i<ji,j,i<j交换Ai,AjA_i,A_jAi​,Aj ...

  2. 2021牛客暑期多校训练营2 G.League of Legends(转化+单调队列)

    G.League of Legends Zechariah_2001题解 对于可以包含其他区间的大区间,要使得答案最优无非就是两种分组方式:单独一组或者与被包含的区间一组.单独一组那么贡献就是区间长度 ...

  3. 2021牛客暑期多校训练营9

    2021牛客暑期多校训练营9 题号 题目 知识点 A A Math Challenge B Best Subgraph C Cells D Divide-and-conquer on Tree E E ...

  4. 2021牛客暑期多校训练营5

    2021牛客暑期多校训练营5 题号 题目 知识点 A Away from College B Boxes 概率 C Cheating and Stealing D Double Strings 线性d ...

  5. 2021牛客暑期多校训练营4

    2021牛客暑期多校训练营4 题号 题目 知识点 A Course B Sample Game C LCS D Rebuild Tree E Tree Xor 思维+线段树 F Just a joke ...

  6. 2021牛客暑期多校训练营3

    2021牛客暑期多校训练营3 题号 题目 知识点 A Guess and lies B Black and white C Minimum grid 二分图匹配 D Count E Math 数论+打 ...

  7. 2021牛客暑期多校训练营2

    2021牛客暑期多校训练营2 题号 题目 知识点 A Arithmetic Progression B Cannon C Draw Grids D Er Ba Game E Gas Station F ...

  8. 2021牛客暑期多校训练营1

    2021牛客暑期多校训练营1 题号 题目 知识点 难度 A Alice and Bob 博弈论 B Ball Dropping 计算几何 签到 C Cut the Tree D Determine t ...

  9. 2021牛客暑期多校训练营2,签到题CDFKI

    2021牛客暑期多校训练营2 题号 标题 已通过代码 通过率 团队的状态 A Arithmetic Progression 点击查看 6/72 未通过 B Cannon 点击查看 34/104 未通过 ...

  10. 2021牛客暑期多校训练营1, 签到题DFBG

    2021牛客暑期多校训练营1 题号 标题 已通过代码 通过率 团队的状态 A Alice and Bob 点击查看 1365/5586 通过(博弈论-打表) B Ball Dropping 点击查看 ...

最新文章

  1. 33 ES6中的类和对象
  2. 马鞍山职业计算机考试,2020年职业适应性(技能)测试纲要
  3. eclipse下载,安装,JDk环境配置教程
  4. MySQL数据库创建用户_修改用户_删除用户_设置用户
  5. java中线程观察者模式_设计模式之--观察者模式
  6. 在bash中,如何检查字符串是否以某个值开头?
  7. 洛谷1123 取数游戏
  8. mysql carnation_RDS mysql5.6 数据库还原到本地
  9. iOS POST 上传图片
  10. java ssm 答辩_基于SSM的网上书店商城设计现场答辩记录
  11. [Unity官方教程]Tanks!单机双人坦克大战源码和素材
  12. 路由交换的一些常见知识点总结
  13. 天气 android 源码,android 天气预报app源码
  14. 64位mysql 和32位区别_32位和64位哪个好 区别的对比分析
  15. jsp 按照学号查找学生_​全国学籍号查询平台:https://my.chsi.com.cn/archive/index.jsp...
  16. 【GNSS发展历史】
  17. matlab中sum对矩阵求和以及size用法
  18. 08-SNAP的命令行处理工具gpt及其批处理(Sentinel-1和Sentinel-2为例)
  19. 王者链游西坦竞技场(Thetan Arena)攻略来了
  20. 数字格式化、大数据BigDecimal、随机数生成方法random()

热门文章

  1. php获取某地的ip,php获取本土实际IP
  2. 2020项目商机_2020未来商机,一万元可以做什么项目
  3. 在每个运行中运行多个查询_在Kubernetes中运行OpenEBS
  4. qint64转为qstring qt_Qt中Qstring,char,int,QByteArray之间到转换
  5. vba 不等于_EXCEL中VBA基础语句(1)
  6. C++string容器-插入和删除
  7. 数据结构与算法--丑数
  8. slot属性值_深入理解vue中的slot与slot
  9. word List 17
  10. ImportError: libicui18n.so.56 and/or libicui18n.so.58 when importing cv2