bzoj

题面放一下

Description

WC2014后无数人来膜拜jc,但是来膜拜的人实在太多了, 而且很多人是一连膜拜好几天。所以jc给这些人建了一座树 形的宿舍,而根节点(1号节点)住着jc。然而,由于设计 的原因,宿舍中只有一个水龙头。于是晚上打水就成了问题。 所有人都有一个大小不同的水桶,第i个结点住着的人的水 桶灌满要Ti的时间。水龙头一开始在jc的宿舍,但是水龙 头的位置会发生变化。当一个人去打水,他走的一定是到水 龙头的最短距离,而且他路过的所有宿舍中住的人都会和他 一起去打水。现在有n个人入住,发生了m个事件。

1.C i 表示水龙头在第i个宿舍

2.Q i 表示住在i宿舍的人出发去打水。

对于每个Q i,你需要告诉jc这次去打水的所有人最少的 总等待时间。

Input

第一行三个整数n,m,key,接下来一行n个整数表示Ti(小于等于10^7),接下来一行n个数表示每个节点的父亲,保证根节点的父亲为0。接下来m行每行表述一个事件。对于每个Q操作,若输入为Q k,则实际的\(k=(k+(pre \% 2)*key) \% n+1\),\(pre\)为上一个询问的答案,若是第一个 询问则\(pre=0\)。一开始水龙头在1号节点。

sol

每一次的询问就是查询树上从\(k\)点到水龙头位置的路径信息。

想写树上莫队。发现强制在线?

仔细想一下发现这个强制在线是假的,因为一来修改操作没有加密,二来\(pre\)只会导致询问有两种不同可能。只要对这两种分别求解在输出的时候判一下就好了。

莫队维护的东西是所有人的总等待时间。按照贪心的思路,显然是打水时长小的人排在前面。

我们现在考虑新加入一个打水时长为\(time\)的人。那么这个人就要想办法插到打水队伍里面。因为打水时间相同的人顺序任意,我们假设他插到了与他打水时间相同的所有人中的最后一个位置。

那么这时候,排在他前面的人的等待时间不会变。他自己的等待时间为\(time+\)所有排在他前面,打水时间小于等于\(time\)的时长之和。而排在他后面的人,每个人的打水时长都增加了\(time\)。

所以就能轻松地写出每次加入/删除一个点后答案的变化量了。

把打水时间离散化后相当于前缀和、后缀和的形式,直接树状数组一波。

code

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 1e5+5;
int n,block,m,key,val[N],o[N],len,to[N<<1],nxt[N<<1],head[N],cnt;
int fa[N],dep[N],sz[N],son[N],top[N],dfn[N];
int ccnt,bl[N],s[N],tp,lst=1,vis[N];
ll c1[N],c2[N],Ans,ans[N],pre;
struct query{
int u,v,id;
bool operator < (const query &b) const
{
if (bl[u]!=bl[b.u]) return bl[u]<bl[b.u];
return bl[v]<bl[b.v];
}
}q[N];
void link(int u,int v){to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;}
void dfs1(int u,int f)
{
fa[u]=f;dep[u]=dep[f]+1;sz[u]=1;
for (int e=head[u];e;e=nxt[e])
{
int v=to[e];if (v==f) continue;
dfs1(v,u);
sz[u]+=sz[v];if (sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int up)
{
top[u]=up;dfn[++cnt]=u;int ttp=tp;
if (son[u]) dfs2(son[u],up);
if (tp-ttp>=block) {++ccnt;while (tp>ttp) bl[s[tp--]]=ccnt;}
for (int e=head[u];e;e=nxt[e])
{
int v=to[e];if (v==fa[u]||v==son[u]) continue;
dfs2(v,v);
if (tp-ttp>=block) {++ccnt;while (tp>ttp) bl[s[tp--]]=ccnt;}
}
s[++tp]=u;
}
int getlca(int u,int v)
{
while (top[u]^top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
void Add(int pos,int val)
{
for (int k=pos;k<=len;k+=k&-k)
c1[k]+=val*o[pos],c2[k]+=val;
}
ll Sum(int k){ll res=0;while(k)res+=c1[k],k^=k&-k;return res;}
ll Size(int k){ll res=0;while(k)res+=c2[k],k^=k&-k;return res;}
void update(int x)
{
if (!vis[x])
{
Ans+=o[val[x]]+Sum(val[x])+(ll)o[val[x]]*(Size(len)-Size(val[x]));
Add(val[x],1);vis[x]=1;
}
else
{
Add(val[x],-1);vis[x]=0;
Ans-=o[val[x]]+Sum(val[x])+(ll)o[val[x]]*(Size(len)-Size(val[x]));
}
}
void change(int u,int v)
{
while (u^v)
if (dep[u]>dep[v]) update(u),u=fa[u];
else update(v),v=fa[v];
}
int main()
{
n=gi();block=pow(n,0.6);m=gi();key=gi();
for (int i=1;i<=n;++i) val[i]=o[i]=gi();
sort(o+1,o+n+1);len=unique(o+1,o+n+1)-o-1;
for (int i=1;i<=n;++i) val[i]=lower_bound(o+1,o+len+1,val[i])-o;
for (int i=1;i<=n;++i)
{
int f=gi();
if (f) link(f,i),link(i,f);
}
dfs1(1,0);cnt=0;dfs2(1,1);cnt=0;
if (tp) {++ccnt;while (tp) bl[s[tp--]]=ccnt;}
for (int i=1;i<=m;++i)
{
char ch=getchar();
while (ch!='C'&&ch!='Q') ch=getchar();
if (ch=='C') lst=gi();
else{
int k=gi();
q[++cnt]=(query){lst,k%n+1,cnt};
if (dfn[q[i].u]>dfn[q[i].v]) swap(q[i].u,q[i].v);
q[++cnt]=(query){lst,(k+key)%n+1,cnt};
if (dfn[q[i].u]>dfn[q[i].v]) swap(q[i].u,q[i].v);
}
}
sort(q+1,q+cnt+1);
change(q[1].u,q[1].v);
int gg=getlca(q[1].u,q[1].v);
update(gg);ans[q[1].id]=Ans;update(gg);
for (int i=2;i<=cnt;++i)
{
change(q[i].u,q[i-1].u);
change(q[i].v,q[i-1].v);
gg=getlca(q[i].u,q[i].v);
update(gg);ans[q[i].id]=Ans;update(gg);
}
for (int i=1;(i<<1)<=cnt;++i)
if (pre&1) printf("%lld\n",pre=ans[i<<1]);
else printf("%lld\n",pre=ans[(i<<1)-1]);
return 0;
}

[BZOJ3460] Jc的宿舍的更多相关文章

  1. 【BZOJ3460】Jc的宿舍(树上莫队+树状数组)

    点此看题面 大致题意: 一棵树,每个节点有一个人,他打水需要\(T_i\)的时间,每次询问两点之间所有人去打水的最小等待时间. 伪·强制在线 这题看似强制在线,但实际上,\(pre\ mod\ 2\) ...

  2. BZOJ 3460 Jc的宿舍

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3460 题意:一棵树.每个节点住一个人,这个人打水的时间为Ti.每次查询一个路径.这 ...

  3. #YCB#待做题目与填坑资料

    各种填坑资料(qwq) 主席树(by YL)戳 树套树(by ZSY)戳 不要问我这些题咋来的(查大佬的水表呗) 题目列表: [HDU5977]Garden of Eden [BZOJ2752][HA ...

  4. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2375  Solved: 1005[Submit][Sta ...

  7. 2055 [ZJOI2009]假期的宿舍

    P2055 [ZJOI2009]假期的宿舍 题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A ...

  8. BZOJ-1433 假期的宿舍 最大流+基础建图

    网络流练习ing.. 1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1748 Solved: 765 [S ...

  9. bzoj1433: [ZJOI2009]假期的宿舍

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2286  Solved: 969[Submit][Stat ...

随机推荐

  1. ManagementObjectSearcher Path

    为了获取硬件信息,你还需要创建一个ManagementObjectSearcher 对象.ManagementObjectSearcher searcher = new ManagementObjec ...

  2. hibernate之实体@onetomany和@manytoone双向注解(转)

    下面是User类: @onetomany @Entity @Table(name="user") public class User implements Serializable ...

  3. mongodb的TTL索引介绍(超时索引)

    TTL索引是mongodb新支持的用于延时自动删除记录的一种索引.它仅包含一个字段,该字段值需要是Date()类型,并且不支持复合索引.可以指定某条记录在延时固定时间后自动删除.数据自动超时删除主要用 ...

  4. WebView性能优化--独立进程

    Android允许一个app同时存在多个进程,可以根据需要把不同的模块放到不同进程中处理. 一.WebView独立进程的好处 1.有效增大App的运存,减少由webview引起的内存泄露对主进程内存的 ...

  5. 几种优化ajax的执行速度的方法

    1.尽量使用局部的变量,而不使用全局变量: 2.优化for循环 3.尽量少用eval,每次使用eval都需要消耗大量的时间: 4.将DOM节点放在文档上. 5.尽量减少点好(.)操作符号的使用

  6. C#委托与事件--后续补充

    委托.事件补充 针对昨天文章 委托:让方法可以跟简单对象一样作为参数进行传递,也就是将方法作为参数进行封装. 方法:本质就是代码段 其实也好理解,目的就是为了封装,多态,既然简单对象如int i可以做 ...

  7. Python基础——for/while循环

    Python版本:3.6.2  操作系统:Windows  作者:SmallWZQ 上学期间,常常遇到这样的情景:为了惩罚学生,老师会说:"XXX,你先去操场上跑10圈再回来继续反省.&qu ...

  8. sonar + jacoco + mockMvc 模拟session 用户登录 配合SpringSecurity 权限 快速测试代码覆盖率.

    遇到mock 测试简直就是神器,特别是要做代码覆盖率,直接测试controller就好了,缺点,虽然可以回滚事务,但是依赖数据库数据,解决,根据SpringBoot ,再建立一个专门跑单元测试的数据库 ...

  9. java I/O框架 (一)总览

    一.前言 java io框架非常庞大,各种功能的类让人目不暇接,为了系统学习io框架,搜集了各种资料,整理出这篇文章,尽可能详细的讲述java io框架,其中会牵扯到许多信息,不仅包括框架内各种类的方 ...

  10. TI Davinci DM6446开发攻略——开发环境搭建

    TI DAVINCI DM6446的开发环境搭建不像三星S3C2410,S3C2440,ATMEL的AT91SAM9260之类的单核ARM那么简单,因为DM6446还有DSP端的开发环境,以及双核之间 ...