[清华集训2017] Hello World!
Hello world!
题目背景
不远的一年前,小 V 还是一名清华集训的选手,坐在机房里为他已如风中残烛的OI 生涯做最后的挣扎。而如今,他已成为了一名光荣的出题人。他感到非常激动,不禁感叹道: “Hello world!”。
题目描述
小 V 有 \(n\) 道题,他的题都非常毒瘤,所以关爱选手的 ufozgg 打算削弱这些题。为了逃避削弱,小 V 把他的毒瘤题都藏到了一棵 \(n\) 个节点的树里(节点编号从 \(1\) 至 \(n\)),这棵树上的所有节点与小 V 的所有题一一对应。小 V 的每一道题都有一个毒瘤值,节点 \(i\) (表示标号为 \(i\) 的树上节点,下同)对应的题的毒瘤值为 \(a_i\)。
魔法师小 V 为了保护他的题目,对这棵树施了魔法,这样一来,任何人想要一探这棵树的究竟,都必须在上面做跳跃操作。每一次跳跃操作包含一个起点 \(s\) 、一个终点 \(t\) 和一个步频 \(k\) ,这表示跳跃者会从 \(s\) 出发,在树上沿着简单路径多次跳跃到达 \(t\) ,每次跳跃,如果从当前点到 \(t\) 的最短路长度不超过 \(k\) ,那么跳跃者就会直接跳到 \(t\) ,否则跳跃者就会沿着最短路跳过恰好 \(k\) 条边。
既然小 V 把题藏在了树里, ufozgg 就不能直接削弱题目了。他就必须在树上跳跃,边跳跃边削弱题目。 ufozgg 每次跳跃经过一个节点(包括起点 \(s\) ,当 \(s = t\) 的时候也是如此),就会把该节点上的题目的毒瘤值开根并向下取整:即如果他经过了节点 \(i\),他就会使 \(a_i = \lfloor \sqrt{a_i} \rfloor\)。这种操作我们称为削弱操作。
ufozgg 还会不时地希望知道他对题目的削弱程度。因此,他在一些跳跃操作中会放弃对题目的削弱,转而统计该次跳跃经过节点的题目毒瘤值总和。这种操作我们称为统计操作。
吃瓜群众绿绿对小 V 的毒瘤题和 ufozgg 的削弱计划常感兴趣。他现在想知道ufozgg 每次做统计操作时得到的结果。你能帮帮他吗?
输入格式
从文件 helloworld.in 中读入数据。
输入的第一行一个正整数 \(n\) ,表示树的节点数。
接下来一行 \(n\) 个用空格隔开的正整数 \(a_1, a_2, \ldots, a_n\),依次描述每个节点上题目的毒瘤值。
接下来 \(n − 1\) 行,描述这棵树。每行 \(2\) 个正整数 \(u, v\) ,描述一条树上的边 \((u, v)\) 。(保证 \(1 \leq u, v \leq n\) ,保证这 \(n − 1\) 条边构成了一棵树)
接下来一行一个正整数 \(Q\) ,表示 ufozgg 的操作总数。
接下来 \(Q\) 行按 ufozgg 执行操作的先后顺序依次描述每个操作,每行 \(4\) 个用空格隔开的整数 \(op, s, t, k\) ,表示 ufozgg 此次跳跃的起点为 \(s\) ,终点为 \(t\) ,步频为 \(k\) 。如果 \(op = 0\) ,表示这是一次削弱操作;如果 \(op = 1\) ,表示这是一次统计操作。
输出格式
对于每个统计操作,输出一行一个整数,表示此次统计操作统计到的所有题的毒瘤值总和。
样例 #1
样例输入 #1
5
1 2 3 4 5
1 2
2 3
3 4
2 5
5
1 1 4 1
1 1 4 2
0 1 5 2
1 2 4 5
1 1 5 1
样例输出 #1
10
8 6 5
提示
对于 \(100\%\) 的数据,\(n≤50000\), \(Q≤400000\), \(1\leq ai\leq 10^{13}\)。
对于所有的操作保证 \(0\leq op\leq 1\),\(1\leq s,t,k\leq n\)。
引入:
维护一个数据结构支持单点修改,链求和。这个是可以不用树剖的。可以维护一个点到根之和,修改时相当于子树加,链求和可以差分。所以用树状数组维护 dfs 序就可以了。
走 \(k\),步,一个很经典的根号分治的线索。
预处理长剖 \(k\) 级祖先,所有询问都可以在 \(O(\frac{nQ}k)\) 的复杂度以内完成。可以先把 \(t\) 向上跳 \(dis(s,t)\bmod k\) 步,然后 \(s\) 和 \(t\) 一起往上 \(k\) 步的跳。
然后考虑把 \(k\) 比较小的情况维护出来。先看修改,首先一个点开根 \(\log\log a\) 次之后就会变成 1。可以用并查集维护一个点向上跳 \(k\) 步,第一个不为 1 的在哪里。然后我们就可以用引入的内容维护所有的 \(k\) 步,维护 \(dep mod k\) 这条链之和。查询时直接询问链就行了。
如果对 \(B\) 以内的 \(k\) 这样预处理复杂度就是 \(nB\log\log A\log n\)
然后
B 取 \(\sqrt{\frac Q{\log\log a\log n}}\) 时,复杂度取到最优值。但是实测时 B 取 25 最好(常数小?)
#include<bits/stdc++.h>
using namespace std;
const int N=50005,B=25;
typedef long long LL;
int n,fa[B][N],f[N][20],ln[N],son[N],q,in[B][N],out[B][N],top[N],dep[N],lg[N],c;
LL ans,a[N];
vector<int>u[N],d[N],g[N];
vector<LL>tr[B][B];
void upd(int k,int p,int x,LL y)
{
for(int i=x;i<tr[k][p].size();i+=i&-i)
tr[k][p][i]+=y;
}
void sou(int x,int y)
{
f[x][0]=y;
dep[x]=dep[y]+1;
for(int i=1;i<B;i++)
{
in[i][x]=tr[i][dep[x]%i].size();
tr[i][dep[x]%i].push_back(0);
}
for(int i=1;i<20;i++)
f[x][i]=f[f[x][i-1]][i-1];
for(int v:g[x])
{
if(v==y)
continue;
sou(v,x);
if(ln[v]+1>ln[x])
ln[x]=ln[v]+1,son[x]=v;
}
for(int i=1;i<B;i++)
out[i][x]=tr[i][dep[x]%i].size();
}
void dfs(int x,int y,int tp)
{
d[tp].push_back(x);
if(son[x])
dfs(son[x],x,tp);
top[x]=tp;
for(int v:g[x])
if(v^y&&v^son[x])
dfs(v,x,v);
if(x==tp)
{
int y=x;
for(int i=0;i<=ln[x]&&y;i++)
{
u[x].push_back(y);
y=f[y][0];
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])
swap(x,y);
while(dep[x]>dep[y])
x=f[x][lg[dep[x]-dep[y]]];
if(x==y)
return x;
for(int i=19;~i;--i)
if(f[x][i]^f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
int ask(int x,int k)
{
if(!k)
return x;
int p=x,q=lg[k];
assert(dep[x]-k>0);
x=f[x][lg[k]];
assert(x);
k-=1<<lg[k];
if(dep[x]-dep[top[x]]<=k)
return u[top[x]][k-dep[x]+dep[top[x]]];
return d[top[x]][dep[x]-dep[top[x]]-k];
}
int find(int k,int x)
{
if(fa[k][x]==x)
return x;
return fa[k][x]=find(k,fa[k][x]);
}
void upd(int x)
{
if(a[x]==1)
return;
LL t=sqrt(a[x]);
assert(t*t<=a[x]);
while((t+1)*(t+1)<a[x])
++t;
for(int i=1;i<B;i++)
{
upd(i,dep[x]%i,in[i][x],t-a[x]);
upd(i,dep[x]%i,out[i][x],a[x]-t);
}
a[x]=t;
if(a[x]==1)
for(int i=1;i<B&&i<dep[x];i++)
fa[i][x]=find(i,ask(x,i));
}
LL query(int k,int x)
{
int d=dep[x]%k,p=in[k][x];
LL ans=0;
for(;p;p-=p&-p)
ans+=tr[k][d][p];
return ans;
}
int main()
{
for(int i=2;i<N;i++)
lg[i]=lg[i>>1]+1;
for(int i=0;i<B;i++)
{
for(int j=0;j<B;j++)
tr[i][j].push_back(0);
for(int j=1;j<N;j++)
fa[i][j]=j;
}
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",a+i);
for(int i=1,u,v;i<n;i++)
scanf("%d%d",&u,&v),g[u].push_back(v),g[v].push_back(u);
sou(1,0);
dfs(1,0,1);
for(int i=1;i<B;i++)
for(int j=1;j<=n;j++)
if(a[j]==1&&i<dep[j])
fa[i][j]=find(i,ask(j,i));
for(int i=1;i<B;i++)
for(int j=1;j<=n;j++)
upd(i,dep[j]%i,in[i][j],a[j]),upd(i,dep[j]%i,out[i][j],-a[j]);
scanf("%d",&q);
while(q--)
{
int op,s,t,k,d;
scanf("%d%d%d%d",&op,&s,&t,&k);
d=lca(s,t);
int g=(dep[s]+dep[t]-2*dep[d])%k;
if(op)
{
ans=a[t]+a[s];
if(g&&dep[t]-g>=dep[d])
{
t=ask(t,g);
ans+=a[t];
}
if(k>=B)
{
while(dep[s]-k>=dep[d])
{
s=ask(s,k);
ans+=a[s];
}
while(dep[t]-k>=dep[d])
{
t=ask(t,k);
ans+=a[t];
}
}
else
{
if(dep[s]-k>=dep[d])
{
int u=(dep[d]-dep[s]%k+k)%k;
if(!u)
u=k;
ans+=query(k,ask(s,k));
if(dep[d]>u)
ans-=query(k,ask(d,u));
}
if(dep[t]-k>=dep[d])
{
int u=(dep[d]-dep[t]%k+k)%k;
if(!u)
u=k;
ans+=query(k,ask(t,k));
if(dep[d]>u)
ans-=query(k,ask(d,u));
}
}
if(dep[d]%k==dep[s]%k)
ans-=a[d];
printf("%lld\n",ans);
++c;
}
else
{
if(g&&dep[t]-g>dep[d])
{
upd(t);
t=ask(t,g);
}
if(d^t)
upd(t);
if(d^s)
upd(s);
if(k>=B)
{
while(dep[s]-k>dep[d])
{
s=ask(s,k);
upd(s);
}
while(dep[t]-k>dep[d])
{
t=ask(t,k);
upd(t);
}
}
else
{
while(dep[s]-k>dep[d])
{
s=find(k,ask(s,k));
if(dep[s]>dep[d])
upd(s);
}
while(dep[t]-k>dep[d])
{
t=find(k,ask(t,k));
if(dep[t]>dep[d])
upd(t);
}
}
if(dep[s]%k==dep[d]%k||t==d)
upd(d);
}
}
}
[清华集训2017] Hello World!的更多相关文章
- Loj #2331. 「清华集训 2017」某位歌姬的故事
Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...
- Loj #2324. 「清华集训 2017」小 Y 和二叉树
Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...
- Loj #2321. 「清华集训 2017」无限之环
Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...
- Loj 2320.「清华集训 2017」生成树计数
Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...
- 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)
[UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...
- loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主
#2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 "A fight? Co ...
- [LOJ#2330]「清华集训 2017」榕树之心
[LOJ#2330]「清华集训 2017」榕树之心 试题描述 深秋.冷风吹散了最后一丝夏日的暑气,也吹落了榕树脚下灌木丛的叶子.相识数年的Evan和Lyra再次回到了小时候见面的茂盛榕树之下.小溪依旧 ...
- [LOJ#2329]「清华集训 2017」我的生命已如风中残烛
[LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...
- [LOJ#2328]「清华集训 2017」避难所
[LOJ#2328]「清华集训 2017」避难所 试题描述 "B君啊,你当年的伙伴都不在北京了,为什么你还在北京呢?" "大概是因为出了一些事故吧,否则这道题就不叫避难所 ...
- [LOJ#2327]「清华集训 2017」福若格斯
[LOJ#2327]「清华集训 2017」福若格斯 试题描述 小d是4xx9小游戏高手. 有一天,小d发现了一个很经典的小游戏:跳青蛙. 游戏在一个 \(5\) 个格子的棋盘上进行.在游戏的一开始,最 ...
随机推荐
- Linux服务器的性能监控与分析
通过vmstat分析性能 如上图所示,我们在命令vmstat后面添加了两个参数,1表示间隔一秒获取一次,10表示总共获取10次 我们一列一列数据来看: r:代表目前实际运行的指令队列,很高表示CPU ...
- 设置服务账号Service Accounts(sa)的token不挂载到pod
目录 一.系统环境 二.前言 三.Service Accounts(sa)简介 四.在pod里设置sa的token不挂载到pod 五.在sa里设置sa对应的token不挂载到pod上 六.总结 一.系 ...
- 文心一言(ERNIE Bot)初体验
引言 几个月前向百度提交了文心一言的体验申请,这两天收到了可以体验的通知,立马体验了一把.总体来说,文心一言基本上能做到有问必答,但是一些奇葩的问题还是会难住这位初出茅庐的 AI. 分享体验 我先后问 ...
- [超详细]SpringBoot整合WebSocket
1. 什么是WebSocket? WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它允许在浏览器和服务器之间进行实时的.双向的通信.相对于传统的基于请求和响应的 HTTP 协议, ...
- 如何通过拼多多订单API接口获取订单详情
要获取拼多多订单详情,可以使用以下接口: 1. API名称:pdd.order.detail.get 接口说明:此接口用于查询某个订单的详情信息. API文档地址:前往注册 调用该接口需要提供以下参数 ...
- 在 RedHat Enterprise、CentOS 或 Fedora Linux 上安装 MongoDB
在 RedHat Enterprise.CentOS 或 Fedora Linux 上安装 MongoDB 1.大纲 备注:采用yum安装后,所有进程将自动在/usr/bin下,如下的mongo.mo ...
- 4.1 应用层Hook挂钩原理分析
InlineHook 是一种计算机安全编程技术,其原理是在计算机程序执行期间进行拦截.修改.增强现有函数功能.它使用钩子函数(也可以称为回调函数)来截获程序执行的各种事件,并在事件发生前或后进行自定义 ...
- Kafka与RabbitMQ
一.什么是kafka,什么是rabbit Kafka是由Scala语言开发的一种分布式流处理框架,主要用于处理活跃的流式数据,以及大数据量的数据处理.它采用发布-订阅模型,支持消息的批量处理,数据 ...
- kubernates的集群安装-kubadm
kubernates的集群安装-kubadm 环境准备工作(CentOS) 准备三台或以上的虚拟机 停用防火墙 sudo systemctl stop firewalld sudo systemctl ...
- 在C#中如何自定义配置上周和本周起始日来查询业务数据?
作者:西瓜程序猿 主页传送门:https://www.cnblogs.com/kimiliucn 前言 在做某个报表管理功能时,有一个需求:需要根据自定义配置的[周起始日]来统计上周.本周的订单数据. ...