树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法:码码码码码码码码...码完就AC啦. O(M log N)

-------------------------------------------------------------------

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
 
typedef long long ll;
 
const int maxn = 100009;
 
int N, Q, Top, L, R, dfn, T;
int Id[maxn], sz[maxn], dep[maxn], fa[maxn], ch[maxn], top[maxn];
 
inline int getint() {
char c = getchar();
for(; !isdigit(c); c = getchar());
int ret = 0;
for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
return ret;
}
inline ll getll() {
char c = getchar();
for(; !isdigit(c); c = getchar());
ll ret = 0;
for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
return ret;
}
 
struct edge {
int t;
edge* n;
} E[maxn << 1], *Pt = E, *H[maxn];
 
inline void AddEdge(int u, int v) {
Pt->t = v, Pt->n = H[u], H[u] = Pt++;
}
 
void dfs(int x) {
sz[x] = 1, ch[x] = -1;
for(edge* e = H[x]; e; e = e->n) if(e->t != fa[x]) {
dep[e->t] = dep[x] + 1;
fa[e->t] = x;
dfs(e->t);
sz[x] += sz[e->t];
if(!~ch[x] || sz[ch[x]] < sz[e->t]) ch[x] = e->t;
}
}
 
void DFS(int x) {
top[x] = Top;
Id[x] = ++dfn;
if(~ch[x]) DFS(ch[x]);
for(edge* e = H[x]; e; e = e->n)
if(e->t != fa[x] && e->t != ch[x]) DFS(Top = e->t);
}
 
void Init() {
N = getint(), Q =getint();
for(int i = 1; i < N; i++) {
int u = getint() - 1, v = getint() - 1;
AddEdge(u, v), AddEdge(v, u);
}
fa[0] = -1, dep[0] = 0, dfs(0);
DFS(dfn = Top = 0);
}
 
struct Mark {
ll f, d;
Mark() : f(0), d(0) {
}
Mark(ll _f, ll _d) : f(_f), d(_d) {
}
Mark operator += (const Mark o) {
f += o.f, d += o.d;
return *this;
}
Mark Rev(int len) {
return Mark(f + (len - 1) * d, -d);
}
Mark Cut(int len) {
return Mark(f + len * d, d);
}
inline ll Sum(int len, int s = 0) {
return ll(len) * (f + d * s) + (d * len * (len - 1) >> 1);
}
};
 
struct Node {
Node *lc, *rc;
ll sm;
Mark t;
inline void upd(int len) {
if(len > 1) {
sm = lc->sm + rc->sm;
} else
sm = 0;
sm += t.Sum(len);
}
} pool[20000009], *pt, *Root[maxn];
 
void Init_sgt() {
pt = pool;
pt->lc = pt->rc = pt;
pt->t = Mark();
Root[0] = pt++;
}
 
int LCA(int u, int v) {
for(; top[u] != top[v]; u = fa[top[u]])
if(dep[top[u]] < dep[top[v]]) swap(u, v);
return dep[u] < dep[v] ? u : v;
}
 
Node* Modify(Node* t, int l, int r, Mark mk) {
Node* o = pt++;
o->t = t->t;
o->lc = t->lc, o->rc = t->rc;
if(L <= l && r <= R) {
o->t += mk;
} else {
int m = (l + r) >> 1;
if(L <= m) o->lc = Modify(o->lc, l, m, mk);
if(m < R) o->rc = Modify(o->rc, m + 1, r, L <= m ? mk.Cut(m - max(L, l) + 1) : mk);
}
o->upd(r - l + 1);
return o;
}
 
Node* MODIFY(Node* p, int u, int v, Mark t) {
int lca = LCA(u, v);
for(; top[u] != top[v]; u =fa[top[u]]) {
if(dep[top[u]] < dep[top[v]]) {
t = t.Rev(dep[u] + dep[v] - (dep[lca] << 1) + 1);
swap(u, v);
}
L = Id[top[u]], R = Id[u];
p = Modify(p, 1, N, t.Rev(dep[u] - dep[top[u]] + 1));
t = t.Cut(dep[u] - dep[top[u]] + 1);
}
if(dep[u] > dep[v]) {
t = t.Rev(dep[u] - dep[v] + 1);
swap(u, v);
}
L = Id[u], R = Id[v];
p = Modify(p, 1, N, t);
return p;
}
 
void Query(Node* t, int l, int r, Mark o, ll &ret) {
if(L <= l && r <= R) {
ret += t->sm + o.Sum(r - l + 1);
} else {
int m = (l + r) >> 1;
o += t->t;
if(L <= m) Query(t->lc, l, m, o, ret);
if(m < R) Query(t->rc, m + 1, r, o.Cut(m + 1 - l), ret);
}
}
 
ll QUERY(Node* t, int u, int v) {
ll ret = 0;
for(; top[u] != top[v]; u = fa[top[u]]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
L = Id[top[u]], R = Id[u];
Query(t, 1, N, Mark(), ret);
}
if(dep[u] > dep[v]) swap(u, v);
L = Id[u], R = Id[v];
Query(t, 1, N, Mark(), ret);
return ret;
}
 
void Work() {
char c;
int t = 0;
ll ans = 0;
Init_sgt();
Node* Rt = Root[0];
while(Q--) {
scanf(" %c", &c);
if(c == 'c') {
int u = getll() ^ ans, v = getll() ^ ans;
ll f = getll(), d =getll();
Rt = Root[++t] = MODIFY(Rt, u - 1, v - 1, Mark(f, d));
} else if(c == 'q') {
printf("%lld\n", ans = QUERY(Rt, (getll() ^ ans) - 1, (getll() ^ ans) - 1));
} else
Rt = Root[getll() ^ ans];
}
}
 
int main() {
Init();
Work();
return 0;
}

-------------------------------------------------------------------

3221: [Codechef FEB13] Obserbing the tree树上询问

Time Limit: 20 Sec  Memory Limit: 1280 MB
Submit: 295  Solved: 55
[Submit][Status][Discuss]

Description

      小N最近在做关于树的题。今天她想了这样一道题,给定一棵N个节点的树,节点按1~N编号,一开始每个节点上的权值都是0,接下来有M个操作。第一种操作是修改,给出4个整数X,Y,A,B,对于X到Y路径上加上一个首项是A,公差是B的等差数列,因为小N十分谨慎,所以她每做完一个修改操作就会保存一次,初始状态是第0次保存的局面。第二种操作是求和,给出2个整数X,Y,输出X到Y路径上所有节点的权值和。第三种操作是读取之前第X次保存的局面,所有节点的状态回到之前第X次保存的状态。现在请你对每一个求和操作输出答案。

Input

      第一行2个整数N,M表示节点个数和操作次数。
      接下来N-1行每行2个整数Ui,Vi表示了这棵树中Ui和Vi这2个节点间有边相连。
      接下来M行每行先有一个字符表示了操作的类型:
           如果是’c’,那么代表了一个修改操作,接下来有4个整数X1,Y1,A,B,为了使得询问在线,正确的X=X1 xor上次输出的数,Y=Y1 xor上次输出的数,如果之前没有输出过那么当成0。
           如果是’q’,那么代表了一个求和操作,接下来有2个整数X1,Y1,和修改操作一样需要xor上次输出。
           如果是’l’,那么代表了一次读取操作,接下来1个整数X1,正确的X=X1 xor上次输出的数。

Output

 
      对于每一个求和操作,输出求和后的值。

Sample Input

5 7
1 2
2 3
3 4
4 5
c 2 5 2 3
c 3 4 5 10
q 1 3
l 13
q 13 15
l 6
q 6 4

Sample Output

12
7
7

HINT

100%的数据中N,M<=100000,0<=A,B<=1000,0<=X1,Y1<=10^1,修改次数<M/2,不会读取没保存的局面

Source

BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )的更多相关文章

  1. [BZOJ 3221][Codechef FEB13] Obserbing the tree树上询问

    [BZOJ 3221]Obserbing the tree树上询问 题目 小N最近在做关于树的题.今天她想了这样一道题,给定一棵N个节点的树,节点按1~N编号,一开始每个节点上的权值都是0,接下来有M ...

  2. bzoj 3221: Obserbing the tree树上询问 树链剖分+线段树

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3221 题解 啊呀...这是昨天的考试题啊...直接就粘了.. 与4515: [Sdoi2 ...

  3. Codechef TSUM2 Sum on Tree 点分治、李超线段树

    传送门 点分治模板题都不会迟早要完 发现这道题需要统计所有路径的信息,考虑点分治统计路径信息. 点分治之后,因为路径是有向的,所以对于每一条路径都有向上和向下的两种.那么如果一条向上的路径,点数为\( ...

  4. spoj COT - Count on a tree (树上第K小 LCA+主席树)

    链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...

  5. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  6. BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)

    题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...

  7. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  8. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  9. [BZOJ 4771]七彩树(可持久化线段树+树上差分)

    [BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...

随机推荐

  1. Http权威指南笔记(一) URI URL URN 关系

    定义 URI:统一资源标识符(Uniform Resource Indentifier)用来标识服务器上的资源. URL:统一资源定位符(Uniform Resouce Locator)是资源标识符最 ...

  2. uiwebview 播放视频

    先吐槽下 昨天为了做一个链接优酷的视频难死我了  最后找到一个解决办法 就是uiwebview 播放视频,但是问题又出来了  怎么监听视频开始播放呢??? 我从百度着了4个小时 最后无功而返  最后我 ...

  3. (转)C#反射机制详解

    反射的定义:审查元数据并收集关於它的类型信息的能力,元数据(编辑后的基本数据单元)就是一大堆表,编译器会创建一个类定义表,一个字段定义表,一个方法定义表等,System.Reflection命名空间包 ...

  4. sql server sys.object表字段说明

    列名 数据类型 说明 name sysname 对象名. object_id int 对象标识号. 在数据库中是唯一的. principal_id int 如果不是架构所有者,则为单个所有者的 ID. ...

  5. 关于ECharts Java类库的一个jquery插件

    在项目中开发图表功能时用到了Echars和一个关于Echars的java类库(http://git.oschina.net/free/ECharts).这个类库主要目的是方便在Java中构造EChar ...

  6. nginx 禁止非指定域名访问

    nginx 配置如下: server { listen 80 default_server; server_name _; return 404; } # server conf server { l ...

  7. python基础(四)

    内置函数 callable() #判断是否能够被调用执行,可以调用返回True,例如函数和类 chr() #将ascii值转换为字符,例如print(chr(65) )输出为a ord()#将字符转换 ...

  8. iOS中不透明度的查看

    模拟器工具条 Debug-->Color Blended Layers 即中文显示下 调试 -->颜色混合层 绿色代表不透明部分,红色代表透明部分,红色越多对性能影响越大

  9. Es分析

    http://my.oschina.net/lxbzj/blog/138587 http://donlianli.iteye.com/blog/1923017 http://tangzhaohui.n ...

  10. android4.0 禁止横竖屏切换使用 android:configChanges="orientation|keyboardHidden"无效

    android4.0 禁止横竖屏切换使用 android:configChanges="orientation|keyboardHidden"无效    在之前的版本中都是在Man ...