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 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
随机推荐
- python3.x 函数的参数
2016-08-09 15:06:18 位置参数 调用函数时,参数按照位置依次传递给函数 def show(a1,a2,a3,a4): print(a1,a2,a3,a4) show('s','h' ...
- [C/C++]宽字符与控制台程序
转自:http://www.cnblogs.com/zplutor/archive/2010/11/27/1889227.html 在我刚开始学C/C++的时候,字符类型使用的都是char.接触Win ...
- UVA11796 Dog Distance
题意 PDF 分析 问题可以转化为小问题,即两条狗分别在线段上运动. 然后用相对运动知识可以认为甲不动,乙在线段上运动. 小问题就转化为点到线段的最小或最大距离. 时间复杂度\(O(I \times ...
- JsQuick--个人封装的Js库
JsQuick 该库为本人封装的Js库,尚未进行浏览器兼容 /** * 快速框架 版本:1.0.0 * 日期:2015.02.26 * 作者:简楚恩 */ /** * 快速获取控件类 */ var $ ...
- js判断客户端是pc还是手机
function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", " ...
- MATLAB01
在命令行窗口输入edit就会进入代码编写区,编写完毕点击运行后会先进行保存,然后再执行代码,保存时候一定要以英文开头. 数组 创建矩阵: 函数名 描述 zero(m,n) 创建m行n列全零矩阵 one ...
- Oracle 12.1.0.2 对JSON的支持
Oracle 12.1.0.2版本有一个新功能就是可以存储.查询.索引JSON数据格式,而且也实现了使用SQL语句来解析JSON,非常方便.JSON数据在数据库中以VARCHAR2, CLOB或者BL ...
- nodejs 中的 NODE_PATH
在使用 nodejs 开发中我们都免不了要去安装一些第三方模块. 那么你或多或少的遇到过以下一些问题 再继续阅读之前,我们先来弄清楚一个概念. npm install --global xxx 属于全 ...
- unittest--unittest.defaultTestLoader()的方法
unittest.defaultTestLoader(): defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(t ...
- Office 2019 2016 安装破解教程
声明:工具由蓝点网提供支持,密钥为本人收集内容,非转载部分 GVLKs for Office 2019 Product GVLK Office Professional Plus 2019 ...