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]开店的更多相关文章

  1. luogu 3241 [HNOI2015]开店 动态点分治+二分+vector

    独立写出来+想出来的,1.5h就切了~ 建立点分树,然后用 $vector$ 暴力存所有子节点,然后二分一下子就可以了. #include <cstdio> #include <ve ...

  2. 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 ...

  3. [HNOI2015]开店 树链剖分,主席树

    [HNOI2015]开店 LG传送门 蒟蒻表示不会动态淀粉质. 先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离. 把我们要算的东西稍微变下形:\(ans\) \[ = \sum \ ...

  4. 洛谷 P3241 [HNOI2015]开店 解题报告

    P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...

  5. [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)

    4012: [HNOI2015]开店 Time Limit: 70 Sec  Memory Limit: 512 MBSubmit: 2168  Solved: 947[Submit][Status] ...

  6. 【BZOJ4012】[HNOI2015]开店 动态树分治+二分

    [BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...

  7. BZOJ4012 [HNOI2015]开店

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  8. bzoj 4012: [HNOI2015]开店

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  9. bzoj 4012: [HNOI2015]开店 主席树

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

随机推荐

  1. matlab中freqz的用法以及多项式的展开

    对于一个变量a,matlab中定义需要这样 syms a: 定义之后就可以写由变量组成的式子,比如 c=(1+a^-1)^5; 可以用expand(c) 就能把c展开成多项式,每一项的系数就可以看到. ...

  2. 洛谷P2835 刻录光盘

    传送门 题目大意:有光盘可以传着看,问最少从哪几个人分发,能全部传一遍. 题解:缩点后求入度为0的点的个数 代码: #include<iostream> #include<cstdi ...

  3. FastAdmin 将 PHP 框架升级到 ThinkPHP 5.1

    FastAdmin 将 PHP 框架升级到 ThinkPHP 5.1 社区经常有人问什么时候升级到 ThinkPHP 5.1,但是 ThinkPHP 5.1 和 ThinkPHP 5.0 差别非常大, ...

  4. ajax()函数传值中文乱码解决方法介绍

    jquery的ajax()函数传值中文乱码解决方法介绍,需要的朋友可以参考下 复制代码 代码如下: $.ajax({ dataType : ‘json',type : ‘POST',url : ‘ht ...

  5. 安卓apk包重复签名问题

    安卓数字签名指的是对apk包做文件摘要并加密,在安装apk包时做解密和验证以保证包体不被篡改.这里先普及下签名和验证流程.签名文件保存在apk包里META-INF目录下,包含3个文件: 1.后缀为MF ...

  6. FPGA噪声干扰

    在FPGA高速AD采集设计中,PCB布线差会产生干扰.今天小编为大家介绍一些布线解决方案. 1.信号线的等长 以SDRAM或者DDRII为例,数据线,命令线,地址线以及时钟线最好等长,误差不要超过50 ...

  7. C# VS Java

    摘要:C#的语言规范由Microsoft的Anders Hejlsberg与Scott Wiltamuth编写.在当前Microsoft天花乱坠的宣传中,对C#和C++.Java作一番比较总是很有趣的 ...

  8. java.输入水果的编号,求它对应的单价

    总结:可以if-else 循环或switch循环 package com.b; import java.util.Scanner; /*以下4种水果的单价分别是3.00元/公斤,2.50元/公斤,4. ...

  9. Vue.js:表单

    ylbtech-Vue.js:表单 1.返回顶部 1. Vue.js 表单 这节我们为大家介绍 Vue.js 表单上的应用. 你可以用 v-model 指令在表单控件元素上创建双向数据绑定. v-mo ...

  10. chrome打开新标签页插件

    标签(空格分隔): 日常办公,chrome浏览器 一直被chrome浏览器打开新标签页困扰,每次点开一个新标签页还要再去点一下主页,才能打开搜索页面.如果直接点击主页,又会把当前的页面刷掉,实在是非常 ...