Luogu 3241 [HNOI2015]开店
BZOJ 4012权限题
浙科协的网突然炸了,好慌……
据说正解是动态点分治,然而我并不会,我选择树链剖分 + 主席树维护。
设$dis_i$表示$i$到$root(1)$的值,那么对于一个询问$u$,答案为$\sum_{i = 1}^{n}dis_i + n * dis_u - 2 * \sum_{i = 1}^{n}dis_{lca(i, u)}$。
前两个东西很好维护,我们考虑如何维护后面这个$\sum$,对于每一个点我们可以把它到根跳一跳,然后把这个点对答案的贡献加到线段树中,如果再限定一个$[l, r]$的区间,只要把所有年龄排序从小到大排序按照贡献加到主席树中就可以了。
注意一条树链的贡献和线段树上区间的边界要搞清楚。
主席树标记永久化一下比较好,虽然感觉空间是开不下的,但是这题就这么过去了。
时间复杂度$O((n + q)log^2n)$。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll; const int N = 1.5e5 + ;
const int M = 1e7 + ;
const int inf = << ; int n, qn, tot = , head[N], dfsc = , dep[N];
int top[N], fa[N], siz[N], son[N], id[N];
ll P, dis[N], toVal[N], sumE[N], sumDis[N]; struct Edge {
int to, nxt;
ll val;
} e[N << ]; inline void add(int from, int to, ll val) {
e[++tot].to = to;
e[tot].val = val;
e[tot].nxt = head[from];
head[from] = tot;
} struct Item {
int age, id; friend bool operator < (const Item &x, const Item &y) {
if(x.age == y.age) return x.id < y.id;
else return x.age < y.age;
} } a[N]; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void swap(int &x, int &y) {
int t = x; x = y; y = t;
} inline int max(int x, int y) {
return x > y ? x : y;
} inline int min(int x, int y) {
return x > y ? y : x;
} void dfs1(int x, int fat, int depth, ll nowDis) {
fa[x] = fat, dep[x] = depth;
siz[x] = , dis[x] = nowDis;
int maxson = -;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
dfs1(y, x, depth + , nowDis + e[i].val); toVal[y] = e[i].val;
siz[x] += siz[y]; if(siz[y] > maxson) {
maxson = siz[y];
son[x] = y;
}
}
} void dfs2(int x, int topf) {
top[x] = topf, sumE[id[x] = ++dfsc] = toVal[x];
if(!son[x]) return;
dfs2(son[x], topf);
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fa[x] || y == son[x]) continue;
dfs2(y, y);
}
} namespace PSegT {
struct Node {
int lc, rc;
ll sum, cnt;
} s[M]; int root[N], nodeCnt = ; #define lc(p) s[p].lc
#define rc(p) s[p].rc
#define sum(p) s[p].sum
#define cnt(p) s[p].cnt
#define mid ((l + r) >> 1) void ins(int &p, int l, int r, int x, int y, int pre) {
s[p = ++nodeCnt] = s[pre];
if(x <= l && y >= r) {
++cnt(p);
return;
}
sum(p) += sumE[min(y, r)] - sumE[max(x, l) - ]; if(x <= mid) ins(lc(p), l, mid, x, y, lc(pre));
if(y > mid) ins(rc(p), mid + , r, x, y, rc(pre));
} ll query(int p, int l, int r, int x, int y) {
ll res = 1LL * cnt(p) * (sumE[min(y, r)] - sumE[max(x, l) - ]);
if(x <= l && y >= r) return res + sum(p); if(x <= mid) res += query(lc(p), l, mid, x, y);
if(y > mid) res += query(rc(p), mid + , r, x, y); return res;
} } using namespace PSegT; inline void modify(int rt, int x) {
for(; x; x = fa[top[x]])
ins(root[rt], , n, id[top[x]], id[x], root[rt]);
} inline ll solve(int rt, int x) {
ll res = 0LL;
for(; x; x = fa[top[x]])
res += query(root[rt], , n, id[top[x]], id[x]);
return res;
} int main() {
// freopen("Sample.txt", "r", stdin); read(n), read(qn), read(P);
for(int i = ; i <= n; i++) {
read(a[i].age);
a[i].id = i;
} for(int i = ; i < n; i++) {
int x, y; ll v;
read(x), read(y), read(v);
add(x, y, v), add(y, x, v);
}
dfs1(, , , 0LL), dfs2(, ); /* for(int i = 1; i <= n; i++)
printf("%d ", top[i]);
printf("\n"); */ sort(a + , a + + n);
for(int i = ; i <= n; i++) {
sumE[i] += sumE[i - ];
sumDis[i] = sumDis[i - ] + dis[a[i].id];
}
for(int i = ; i <= n; i++) {
root[i] = root[i - ];
modify(i, a[i].id);
} /* for(int i = 1; i <= n; i++)
printf("%lld ", sumE[i]);
printf("\n");
for(int i = 1; i <= n; i++)
printf("%lld ", sumDis[i]);
printf("\n"); */ ll ans = 0LL;
for(int x, l, r; qn--; ) {
read(x), read(l), read(r);
l = (1LL * l + ans) % P, r = (1LL * r + ans) % P;
if(l > r) swap(l, r); l = lower_bound(a + , a + + n, (Item) {l, }) - a;
r = upper_bound(a + , a + + n, (Item) {r, inf}) - a - ; ans = 1LL * (r - l + ) * dis[x] + sumDis[r] - sumDis[l - ] - 2LL * (solve(r, x) - solve(l - , x));
printf("%lld\n", ans);
} return ;
}
Luogu 3241 [HNOI2015]开店的更多相关文章
- luogu 3241 [HNOI2015]开店 动态点分治+二分+vector
独立写出来+想出来的,1.5h就切了~ 建立点分树,然后用 $vector$ 暴力存所有子节点,然后二分一下子就可以了. #include <cstdio> #include <ve ...
- luogu P3241 [HNOI2015]开店
传送门 (下面记年龄为\(a_x\))题目要求的是\[\sum_{x=1}^{n} [a_x\in [l,r]]*dis(x,u)=\sum_{x=1}^{n} [a_x\in [l,r]]*de_x ...
- [HNOI2015]开店 树链剖分,主席树
[HNOI2015]开店 LG传送门 蒟蒻表示不会动态淀粉质. 先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离. 把我们要算的东西稍微变下形:\(ans\) \[ = \sum \ ...
- 洛谷 P3241 [HNOI2015]开店 解题报告
P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...
- [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)
4012: [HNOI2015]开店 Time Limit: 70 Sec Memory Limit: 512 MBSubmit: 2168 Solved: 947[Submit][Status] ...
- 【BZOJ4012】[HNOI2015]开店 动态树分治+二分
[BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...
- BZOJ4012 [HNOI2015]开店
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- bzoj 4012: [HNOI2015]开店
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- bzoj 4012: [HNOI2015]开店 主席树
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
随机推荐
- C语言词法分析:C#源码
今天继续研究代码解析的算法 这个是算法流程图 有图解可能更直观一点: 以下是c#源码: 1using System; 2using System.IO; 3using System.Tex ...
- jslinq 使用总结
最近一直在用 jslinq 感觉还是不错的.用于增强 Array.find() 上重点: 1: 引用 cnpm install jslinq --save (本人用淘宝镜像--npmFQ感觉也不快-- ...
- JUnit4学习
参考:http://www.cnblogs.com/yangxia-test/p/3996120.html JUnit4是一个开源的java单元测试框架,我们只需要引入一个包,就可以使用它的功能 先说 ...
- bzoj 4310 跳蚤——后缀数组+二分答案+贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4310 答案有单调性? 二分出来一个子串,判断的时候需要满足那些字典序比它大的子串都不出现! ...
- python一个简单的web服务器和客户端
服务器: 当客户联系时创建一个连接套接字 从这个连接接收HTTP请求(*) 解释该请求所请求的特定文件 从服务器的文件系统获取该文件 并发送文件内容 ...
- TXT
ANDRIOD: 192.168.199.119 data50803360 zc_3floor kk4836kk kahuna kk1626kk
- 【转】windows下mysql5.1忘记root密码解决方法
步骤如下:1.停止mysql服务(以管理员身份,在cmd命令行下运行) net stop mysql D:\>net stop mysql MySQL 服务正在停止. MySQL 服务已成功停止 ...
- SERDES高速系统(一)
在目前主流厂商的高端FPGA 中都集成了SERDES(串并收发单元)硬核,如Altera的Stratix IV GX器件族内部集成的SERDES单通道支持600Mbit/s到8.5Gbit/s数据熟率 ...
- 利用全局变量$_SESSION和register_shutdown_function自定义会话处理
register_shutdown_function 可以注册一个自定义的函数,在程序运行结束之前 执行. 在做ecshop的二次开发过程中,虽然代码 太老太乱太冗余,但ec的会话处理的设计感觉还是不 ...
- (转)Oracle 临时表用法
本文转载自:http://www.iteye.com/topic/371390 ORACLE的临时表在应用系统中有很大的作用,它可以让用户只能够操作各自的数据中而互不干扰,不用担心会破坏或影响其他SE ...