HDU 5002 Tree (2014年鞍山赛区网络赛F题)

news/2024/10/22 11:34:00/

1.题目描述:点击打开链接

2.解题思路:LCT的模板题

3.代码:

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <vector>using namespace std;const int N = 111111;
const int INF = 1111111111;int n, m;class LCT {
private :struct node {int size, same, rev, val, inc;pair<int, int> value[2];node *child[2], *father;bool isRoot;inline void setChild(node *tmp, int dir) {child[dir] = tmp;tmp->father = this;}inline int isRc() {return father->child[1] == this;}int calc(int v) {int res = 0;if (val == v) {res++;}for(int i = 0; i < 2; i++)for(int j = 0; j < 2; j++) {if (this->child[i]->value[j].first == v) {res += this->child[i]->value[j].second;}}return res;}inline void update() {if (size == 0) {return ;}int maxValue = max(val, max(child[0]->value[0].first, child[1]->value[0].first));value[0] = make_pair(maxValue, this->calc(maxValue));int sec = -INF;if (val != maxValue) {sec = max(sec, val);}for(int i = 0; i < 2; i++)for(int j = 0; j < 2; j++) {if (this->child[i]->value[j].first != maxValue) {sec = max(sec, this->child[i]->value[j].first);}}value[1] = make_pair(sec, this->calc(sec));size = 1 + child[0]->size + child[1]->size;}inline void make(int v) {if (size == 0) {return ;}value[0] = make_pair(v, size);value[1] = make_pair(-INF, 0);same = v;inc = 0;val = v;}inline void add(int v) {if (size == 0) {return ;}inc += v;val += v;if (value[0].first != -INF) {value[0].first += v;}if (value[1].first != -INF) {value[1].first += v;}} inline void reverse() {if (size == 0) {return ;}rev ^= 1;swap(child[0], child[1]);}inline void push() {if (size == 0) {return ;}if (rev) {child[0]->reverse();child[1]->reverse();rev = 0;}if (same != -INF) {child[0]->make(same);child[1]->make(same);same = -INF;}if (inc) {child[0]->add(inc);child[1]->add(inc);inc = 0;}}};typedef node *Node;node mem[N]; int used;Node Null, t[N];Node newNode(int v) {Node temp = &mem[used++];temp->size = 1, temp->same = -INF, temp->rev = 0, temp->val = v, temp->inc = 0;temp->value[0] = make_pair(v, 1);temp->value[1] = make_pair(-INF, 0);temp->child[0] = temp->child[1] = temp->father = Null;temp->isRoot = true;return temp;}void rotate(Node root) {Node father = root->father;father->push(); root->push();int dir = root->isRc();father->setChild(root->child[!dir], dir);if (father->isRoot) {father->isRoot = false;root->isRoot = true;root->father = father->father;} else {father->father->setChild(root, father->isRc());}root->setChild(father, !dir);father->update();}void splay(Node root) {for(root->push(); !root->isRoot; ) {if (root->father->isRoot) {rotate(root);} else {(root->isRc() == root->father->isRc()) ? (rotate(root->father), rotate(root)) : (rotate(root), rotate(root));}}root->update();} void access(Node root, int oper = 0, int val = 0) {for(Node tmp(Null); root != Null; ) {splay(root);if (root->father == Null && oper) {if (oper == 1) {tmp->make(val);root->push();root->child[1]->make(val);root->val = val;root->update();} else if (oper == 2) {tmp->add(val);root->push();root->child[1]->add(val);root->val += val;root->update();}}root->child[1]->isRoot = true;root->child[1] = tmp;root->child[1]->isRoot = false;root->update();tmp = root;root = root->father;}}
public:void init(int n, int val[]) {used = 0;Null = newNode(-INF);Null->father = Null->child[0] = Null->child[1] = Null;Null->size = 0;for(int i = 1; i <= n; i++) {t[i] = newNode(val[i]);}}void Link(int son, int father) {access(t[son]);splay(t[son]);t[son]->father = t[father];t[son]->reverse();}void Cut(int u, int v) {access(t[v]);splay(t[u]);if (t[u]->father == t[v]) {t[u]->father = Null;} else {access(t[u]);splay(t[v]);if (t[v]->father == t[u]) {t[v]->father = Null;}}}void makeSame(int u, int v, int val) {access(t[u]);access(t[v], 1, val);}void add(int u, int v, int val) {access(t[u]);access(t[v], 2, val);}pair<int, int> getValue(int u, int v) {access(t[u]);Node root = t[v];pair<int, int> res;for(Node tmp(Null); root != Null; ) {splay(root);if (root->father == Null) {root->push();Node a = tmp, b = root->child[1];vector<int> vv;vv.push_back(root->val);for(int i = 0; i < 2; i++) {vv.push_back(a->value[i].first);vv.push_back(b->value[i].first);} sort(vv.begin(), vv.end());vv.erase(unique(vv.begin(), vv.end()), vv.end());reverse(vv.begin(), vv.end());while(vv.size() && vv.back() == -INF) {vv.pop_back();}if (vv.size() == 1) {res = make_pair(-INF, 0);} else {res = make_pair(vv[1], 0);for(int i = 0; i < 2; i++) {if (a->value[i].first == vv[1]) {res.second += a->value[i].second;}if (b->value[i].first == vv[1]) {res.second += b->value[i].second;}}res.second += (root->val == vv[1]);}}root->child[1]->isRoot = true;root->child[1] = tmp;root->child[1]->isRoot = false;root->update();tmp = root;root = root->father;}return res;}
}tree;int main() {int test;scanf("%d", &test);while(test--) {static int testCount = 0;printf("Case #%d:\n", ++testCount);scanf("%d %d", &n, &m);static int val[N];for(int i = 1; i <= n; i++) {scanf("%d", &val[i]);}tree.init(n, val);for(int i = 1; i < n; i++) {int a, b;scanf("%d %d", &a, &b);tree.Link(a, b);}for(int i = 1; i <= m; i++) {int type, a, b, x, y;scanf("%d", &type);if (type == 1) {scanf("%d %d %d %d", &x, &y, &a, &b);tree.Cut(x, y);tree.Link(a, b);} else if (type == 2) {scanf("%d %d %d", &a, &b, &x);tree.makeSame(a, b, x);} else if (type == 3) {scanf("%d %d %d", &a, &b, &x);tree.add(a, b, x);} else {int a, b;scanf("%d %d", &a, &b);pair<int, int> temp = tree.getValue(a, b);if (temp.first == -INF) {printf("ALL SAME\n");} else {printf("%d %d\n", temp.first, temp.second);}}}}return 0;
}


http://www.ppmy.cn/news/712780.html

相关文章

P5002 专心OI - 找祖先

P5002 专心OI - 找祖先 给定一棵有根树&#xff08;\(n \leq 10000\)&#xff09;&#xff0c;\(M \leq 50000\) 次询问&#xff0c; 求以 \(x\) 为 \(LCA\) 的点对个数 错误日志&#xff1a; 看下面 Solution 设点 \(u\) 的子树大小为 \(size[u]\) 现询问以 \(u\) 为 \(LCA\) …

Server com.webank.webase.front.Application Port 5002..Failed

ubuntu打开端口5000和5002 Ubuntu20.04LTS开启22端口 https://blog.csdn.net/m0_38068876/article/details/121115598

E - The Queue UVALive - 5002 树形dp

题目链接 题意&#xff1a;n个人排队&#xff0c;每个人b除CEO外都有一个监督人a&#xff0c;b必须排在a的后面&#xff0c;问有多少排队方案。 思路: 这是一道树形dp和组合数学的题目,当时训练的时候公式推对了 ,但是写的时候想错了... 这道题我一看是n个点 n-1个边 又有上下…

UVALive 5002 The Queue (树形Dp)

题意&#xff1a; 在某些特殊场合&#xff0c;Nadia公司为公司所有员工提供非常特别的午餐。 食物供应前&#xff0c;所有员工必须站在食品柜台前排队。 公司应用了排队队列的规则。 这个规则是没有人可以在他的主管面前的任何地方。 例如&#xff0c;如果Abul是Babul的负责人…

卜若的代码笔记系列-unity系列-第二章:json2-5002

1.我们返回对象数组时&#xff0c;请注意&#xff0c;来自于服务器的恶意&#xff1a; 2.这个时候我们就需要自行组装字符串了 //1.将字符串按,拆解 //2.将字符数组‘&#xff0c;’组装 //3.退格“}” 完成 IEnumerator ieReuqest(){var request (HttpWebRequest)WebRequest…

HDU 5002(概率题目)

分析&#xff1a; 本题目要分开求每一个最大值为x的概率&#xff0c;要求这一个可以先求小于等于x的概率&#xff0c;然后用p[x]-p[x-1]计算得出&#xff0c;最大值为x的概率。 假定当前最大值为x。 那么定义f[ i ]为还有i轮结束&#xff0c;是的最大值不超过x的概率。 p1(出…

UVALive - 5002 The Queue树形dp

https://icpcarchive.ecs.baylor.edu/index.php?optioncom_onlinejudge&Itemid8&pageshow_problem&problem3003 题意是有n个员工&#xff0c;n-1条关系&#xff0c;a b &#xff0c;a是b的上司&#xff0c;很明显树形结构 排队时&#xff0c;上司必须要在前面&…

Mysql报错5002 - cannot modify reserved database

从报错上来看是因为没有选择数据库导致的&#xff0c;但实际上我在navicat里面选择了mysql库&#xff1b;百度没有这个报错的解释与客服沟通后发现该问题是因为没有业务库导致的&#xff1b;在ECS的自建库里面&#xff0c;直接use mysql&#xff0c;然后进行操作都是OK的但是RD…