当前位置: 首页 > news >正文

泉州网站优化排名长沙制作网站公司

泉州网站优化排名,长沙制作网站公司,小程序商店助手,网站手机端设计目描述S 国有 N 个城市,编号从 1 到 N。城市间用 N−1 条双向道路连接,满足从一个城市出发可以到达其它所有城市。每个城市信仰不同的宗教,如飞天面条神教、隐形独角兽教、绝地教都是常见的信仰。为了方便,我们用不同的正整数代表…

目描述

S 国有 N 个城市,编号从 1 到 N。城市间用 N−1 条双向道路连接,满足从一个城市出发可以到达其它所有城市。每个城市信仰不同的宗教,如飞天面条神教、隐形独角兽教、绝地教都是常见的信仰。

为了方便,我们用不同的正整数代表各种宗教,S 国的居民常常旅行。旅行时他们总会走最短路,并且为了避免麻烦,只在信仰和他们相同的城市留宿。当然旅程的终点也是信仰与他相同的城市。S 国为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值。

在 S 国的历史上常会发生以下几种事件:

  • CC x c:城市 x 的居民全体改信了 c 教;
  • CW x w:城市 x 的评级调整为 w;
  • QS x y:一位旅行者从城市 x 出发,到城市 y,并记下了途中留宿过的城市的评级总和;
  • QM x y:一位旅行者从城市 x 出发,到城市 y,并记下了途中留宿过的城市的评级最大值。

由于年代久远,旅行者记下的数字已经遗失了,但记录开始之前每座城市的信仰与评级,还有事件记录本身是完好的。请根据这些信息,还原旅行者记下的数字。 为了方便,我们认为事件之间的间隔足够长,以致在任意一次旅行中,所有城市的评级和信仰保持不变。

输入格式

输入的第一行包含整数 N,Q 依次表示城市数和事件数。

接下来 N 行,第 i+1 行两个整数 Wi​,Ci​ 依次表示记录开始之前,城市 i 的评级和信仰。

接下来 N−1 行每行两个整数 x,y 表示一条双向道路。

接下来 Q 行,每行一个操作,格式如上所述。

输出格式

对每个 QS 和 QM 事件,输出一行,表示旅行者记下的数字。

输入输出样例

输入 #1复制

5 6
3 1
2 3
1 2
3 3
5 1
1 2
1 3
3 4
3 5
QS 1 5
CC 3 1
QS 1 5
CW 3 3
QS 1 5
QM 2 4

输出 #1复制

8
9
11
3

说明/提示

对于 100% 的数据,N,Q≤105,C≤105

数据保证对所有 QS 和 QM 事件,起点和终点城市的信仰相同;在任意时刻,城市的评级总是不大于 104 的正整数,且宗教值不大于 C。

代码实现:

#include <bits/stdc++.h>
using namespace std;
#define mid ((left+right)>>1)

const int MAXN = 110000;
char operation[3];

int cityCount, queryCount;
int cityRating[MAXN], cityReligion[MAXN];
int adjacencyHead[MAXN], edgeCount, nodeCount;
int heavySon[MAXN], subtreeSize[MAXN], parent[MAXN], depth[MAXN];
int nodeID[MAXN], currentID, ratingValue[MAXN], chainTop[MAXN], segmentRoot[MAXN];

struct Edge {
int next, to;
} edges[MAXN << 1];

struct SegmentTreeNode {
int leftChild, rightChild;
int sum, maxValue;
bool flag;
} treeNodes[MAXN << 4];

inline void addEdge(int from, int to) {
edges[++edgeCount].next = adjacencyHead[from];
adjacencyHead[from] = edgeCount;
edges[edgeCount].to = to;
}

void dfsForHeavyLightDecomposition1(int currentNode, int parentNode) {
depth[currentNode] = depth[parentNode] + 1;
parent[currentNode] = parentNode;
subtreeSize[currentNode] = 1;

for (int i = adjacencyHead[currentNode]; i; i = edges[i].next) {
int neighbor = edges[i].to;
if (neighbor == parentNode) continue;

dfsForHeavyLightDecomposition1(neighbor, currentNode);
subtreeSize[currentNode] += subtreeSize[neighbor];

if (subtreeSize[neighbor] > subtreeSize[heavySon[currentNode]])
heavySon[currentNode] = neighbor;
}
}

void dfsForHeavyLightDecomposition2(int currentNode, int topNode) {
nodeID[currentNode] = ++currentID;
ratingValue[currentID] = cityRating[currentNode];
chainTop[currentNode] = topNode;

if (!heavySon[currentNode]) return;
dfsForHeavyLightDecomposition2(heavySon[currentNode], topNode);

for (int i = adjacencyHead[currentNode]; i; i = edges[i].next) {
int neighbor = edges[i].to;
if (neighbor != heavySon[currentNode] && neighbor != parent[currentNode])
dfsForHeavyLightDecomposition2(neighbor, neighbor);
}
}

inline void updateParentNode(int nodeIndex) {
treeNodes[nodeIndex].sum = treeNodes[treeNodes[nodeIndex].leftChild].sum + 
treeNodes[treeNodes[nodeIndex].rightChild].sum;
treeNodes[nodeIndex].maxValue = max(treeNodes[treeNodes[nodeIndex].leftChild].maxValue,
treeNodes[treeNodes[nodeIndex].rightChild].maxValue);
}

void insertNode(int position, int left, int right, int &currentNode, int value) {
if (!currentNode) currentNode = ++nodeCount;

treeNodes[currentNode].maxValue = max(treeNodes[currentNode].maxValue, value);
treeNodes[currentNode].sum += value;

if (left == right) return;

if (position <= mid) 
insertNode(position, left, mid, treeNodes[currentNode].leftChild, value);
else 
insertNode(position, mid + 1, right, treeNodes[currentNode].rightChild, value);
}

void removeNode(int position, int left, int right, int &currentNode) {
if (left == right) {
treeNodes[currentNode].sum = treeNodes[currentNode].maxValue = 0;
return;
}

if (position <= mid) 
removeNode(position, left, mid, treeNodes[currentNode].leftChild);
else 
removeNode(position, mid + 1, right, treeNodes[currentNode].rightChild);

updateParentNode(currentNode);
}

int querySum(int queryLeft, int queryRight, int left, int right, int currentNode) {
if (left >= queryLeft && right <= queryRight) 
return treeNodes[currentNode].sum;

int result = 0;
if (queryLeft <= mid) 
result += querySum(queryLeft, queryRight, left, mid, treeNodes[currentNode].leftChild);
if (queryRight > mid) 
result += querySum(queryLeft, queryRight, mid + 1, right, treeNodes[currentNode].rightChild);

return result;
}

int queryPathSum(int startNode, int endNode, int religion) {
int result = 0;

while (chainTop[startNode] != chainTop[endNode]) {
if (depth[chainTop[startNode]] < depth[chainTop[endNode]])
swap(startNode, endNode);

result += querySum(nodeID[chainTop[startNode]], nodeID[startNode], 1, cityCount, segmentRoot[religion]);
startNode = parent[chainTop[startNode]];
}

if (depth[startNode] > depth[endNode])
swap(startNode, endNode);

result += querySum(nodeID[startNode], nodeID[endNode], 1, cityCount, segmentRoot[religion]);
return result;
}

int queryMax(int queryLeft, int queryRight, int left, int right, int currentNode) {
if (left >= queryLeft && right <= queryRight) 
return treeNodes[currentNode].maxValue;

int result = 0;
if (queryLeft <= mid) 
result = max(result, queryMax(queryLeft, queryRight, left, mid, treeNodes[currentNode].leftChild));
if (queryRight > mid) 
result = max(result, queryMax(queryLeft, queryRight, mid + 1, right, treeNodes[currentNode].rightChild));

return result;
}

int queryPathMax(int startNode, int endNode, int religion) {
int result = 0;

while (chainTop[startNode] != chainTop[endNode]) {
if (depth[chainTop[startNode]] < depth[chainTop[endNode]])
swap(startNode, endNode);

result = max(result, queryMax(nodeID[chainTop[startNode]], nodeID[startNode], 1, cityCount, segmentRoot[religion]));
startNode = parent[chainTop[startNode]];
}

if (depth[startNode] > depth[endNode])
swap(startNode, endNode);

result = max(result, queryMax(nodeID[startNode], nodeID[endNode], 1, cityCount, segmentRoot[religion]));
return result;
}

int main() {
ios::sync_with_stdio(false);
cin >> cityCount >> queryCount;

for (int i = 1; i <= cityCount; i++)
cin >> cityRating[i] >> cityReligion[i];

for (int i = 1, u, v; i < cityCount; i++) {
cin >> u >> v;
addEdge(u, v);
addEdge(v, u);
}

dfsForHeavyLightDecomposition1(1, 0);
dfsForHeavyLightDecomposition2(1, 1);

for (int i = 1; i <= cityCount; i++)
insertNode(nodeID[i], 1, cityCount, segmentRoot[cityReligion[i]], cityRating[i]);

for (int i = 1, x, y; i <= queryCount; i++) {
cin >> operation >> x >> y;

if (operation[1] == 'C') {
removeNode(nodeID[x], 1, cityCount, segmentRoot[cityReligion[x]]);
insertNode(nodeID[x], 1, cityCount, segmentRoot[y], cityRating[x]);
cityReligion[x] = y;

else if (operation[1] == 'W') {
removeNode(nodeID[x], 1, cityCount, segmentRoot[cityReligion[x]]);
insertNode(nodeID[x], 1, cityCount, segmentRoot[cityReligion[x]], y);
cityRating[x] = y;

else if (operation[1] == 'S') {
printf("%d\n", queryPathSum(x, y, cityReligion[x]));

else if (operation[1] == 'M') {
printf("%d\n", queryPathMax(x, y, cityReligion[x]));
}
}

return 0;
}

http://www.dtcms.com/a/510001.html

相关文章:

  • 深圳设计网站公司torrentkitty磁力猫
  • 一学一做看视频网站网络营销大师排行榜
  • 网站建设优化教程全国中小企业网
  • 网站建设招标书模板wordpress自定义前端
  • 网站建设 启象科技孟村网站建设
  • 类网站建设江门市蓬江区最新发布
  • 军博网站建设公司成都的科技公司有哪些
  • 北京网站的建立的国泰君安建设工程官方网站
  • 怎样建立免费的个人网站软件工程属于什么专业类别
  • 网站备案为什么要闭站长春哪家公司做网站好
  • ph域名网站网站内容方案
  • 石油网站编辑怎么做全网营销解决方案
  • 做mip网站必须备案吗手机网页无法访问
  • 网站免费空间哪里申请余姚市城乡建设局网站
  • 要写网站建设方案网站建设 秦皇岛公司哪家好
  • 网站建设克隆wordpress ueditor
  • 网站首次备案网站策划与运营
  • 搭建个人网站赚钱企业网站优化咨询
  • 网站框架怎么搭建wordpress 首页调用栏目文章
  • 58同城商业后台如何做网站wordpress 警告
  • 做环境设计的网站深圳建网站多少钱
  • 网站开发的人李海涛邢台123网站模板
  • 外贸网站使用什么品牌国外主机wordpress搭建
  • 阿里云服务器wordpress建站教程动画设计图
  • 这几年做啥网站致富wordpress传文件
  • 网站如何做中英文双语言版本软装设计公司排行
  • 山东营销网站建设设计福州网站建设哪家强
  • 网站备案号查询平台女生学电子商务后悔了
  • 汕头网站推广费用汨罗网站建设
  • wordpress 足球sem和seo的区别