posts - 129,comments - 0,views - 37707

3531: [Sdoi2014]旅行

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 323  Solved: 192
[Submit][Status]

Description

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

Input

    输入的第一行包含整数N,Q依次表示城市数和事件数。
    接下来N行,第i+l行两个整数Wi,Ci依次表示记录开始之前,城市i的
评级和信仰。
    接下来N-1行每行两个整数x,y表示一条双向道路。
    接下来Q行,每行一个操作,格式如上所述。

Output

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

Sample Input

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

Sample Output

8
9
11
3

HINT

N,Q < =10^5    , C < =10^5


 数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时

刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。

Source

Round 1 Day 1

 

这题题意是每个点有a,b两个值, 询问路径x,y中a值跟x相同的b值的最大值或者和

树链剖分,给每个a值建一颗线段树,然后动态开点,复杂度log^2(n)

没啥trick

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
Author:wuhuajun
*/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define lson l, mid, seg[rt].l
#define rson mid+1, r, seg[rt].r
using namespace std;
  
typedef long long ll;
typedef double dd;
const int maxn=200010;
const int maxq = 20000010;
  
int edge, n, fa[maxn], sz[maxn], son[maxn], dep[maxn], hash[maxn], top[maxn];
int h[maxn], num , x, y, tx, ty, Q, a[maxn], b[maxn], node, rel;
char s[22];
  
struct Edge
{
    int to, ne;
} e[maxn * 2];
  
struct Seg
{
    int maxx, sum, l, r;
    void clear()
    {
        maxx = -1000000000;
        sum = 0;
    }
} seg[maxq], ret, ans;
  
  
void close()
{
    exit(0);
}
  
void addedge(int x,int y)
{
    e[edge].to = y;
    e[edge].ne = h[x];
    h[x] = edge++;
}
  
void dfs(int k,int from)
{
    sz[k] = 1;
    son[k] = 0;
    dep[k] = dep[from] + 1;
    for (int p=h[k];p!=-1;p=e[p].ne)
    {
        int to = e[p].to;
        if (from == to) continue;
        fa[to] = k;
        dfs(to, k);
        sz[k] += sz[to];
        if (sz[to] > sz[son[k]]) son[k] = to;
    }
}
  
void build(int k,int from)
{
    hash[k] = ++num;
    top[k] = from;
    if (son[k]) build(son[k], from);
    for (int p=h[k];p!=-1;p=e[p].ne)
    {
        int to = e[p].to;
        if (to != fa[k] && to != son[k])
            build(to, to);
    }
}
  
//{{{Segment部分
void new_node(int rt)
{
    if (seg[rt].l == 0) seg[rt].l = ++node;
    if (seg[rt].r == 0) seg[rt].r = ++node;
}
  
Seg update(Seg a,Seg b)
{
    Seg c;
    c.sum = a.sum + b.sum;
    c.maxx = max(a.maxx, b.maxx);
    return c;
}
  
void pushup(int rt)
{
    seg[rt].maxx = max(seg[seg[rt].l].maxx, seg[seg[rt].r].maxx);
    seg[rt].sum = seg[seg[rt].l].sum + seg[seg[rt].r].sum;
}
  
void change(int L,int R,int val,int l,int r,int rt)
{
    new_node(rt);
    if (L <= l && r <= R)
    {
        seg[rt].sum = seg[rt].maxx = val;
        return;
    }
    int mid = (l + r) >> 1;
    if (L <= mid)
        change(L,R,val,lson);
    if (mid + 1 <= R)
        change(L,R,val,rson);
    pushup(rt);
}
  
Seg query(int L,int R,int l,int r,int rt)
{
    new_node(rt);
    if (L <= l && r <= R)
    {
        return seg[rt];
    }
    int mid = (l + r) >> 1;
    Seg ans;
    ans.clear();
    if (L <= mid)
        ans = update(ans, query(L,R,lson));
    if (mid + 1 <= R)
        ans = update(ans, query(L,R,rson));
    return ans;
}
  
//}}}
  
Seg get_ans()
{
    tx = top[x];
    ty = top[y];
    ans.clear();
    while (tx != ty)
    {
        if (dep[tx] < dep[ty])
        {
            swap(tx, ty);
            swap(x, y);
        }
        ans = update(ans, query(hash[tx], hash[x], 1, n, rel));
        x = fa[tx];
        tx = top[x];
    }
    if (dep[x] > dep[y]) swap(x, y);
    return update(ans, query(hash[x], hash[y], 1, n, rel));
}
  
void init()
{
    scanf("%d %d",&n, &Q);
    memset(h,-1,sizeof(h));
    for (int i=1;i<=n;i++)
    {
        scanf("%d %d",&b[i], &a[i]);
    }
    for (int i=1;i<=n-1;i++)
    {
        scanf("%d %d",&x, &y);
        addedge(x, y);
        addedge(y, x);
    }
    for (int i=1;i<=n;i++)
        scanf("%d", &a[i]);
    dfs(1, 0);
    build(1, 1);
    node = n;
    /*
       for (int i=1;i<=n;i++)
       {
       printf("i:%d top:%d hash:%d\n",i, top[i], hash[i]);
       }
       */
    for (int i=1;i<=n;i++)
        change(hash[i], hash[i], b[i], 1, n, a[i]); // a -> 宗教 b -> 评级
    while (Q--)
    {
        scanf("%s %d %d", s, &x, &y);
        if (s[1] == 'C')
        {
            change(hash[x], hash[x], 0, 1, n, a[x]); //把本属于宗教a[i]的x点评级改成0;
            a[x] = y;
            change(hash[x], hash[x], b[x], 1, n, a[x]); //把本属于宗教a[i]的x点评级改成现有的
        }
        if (s[1] == 'W')
        {
            b[x] = y;
            change(hash[x], hash[x], y, 1, n, a[x]);
        }
        if (s[1] == 'S')
        {
            rel = a[x];
            ret = get_ans();
            printf("%d\n", ret.sum);
        }
        if (s[1] == 'M')
        {
            rel = a[x];
            ret = get_ans();
            printf("%d\n", ret.maxx);
        }
    }
}
  
int main ()
{
    init();
    close();
    return 0;
}

 

posted on   cssystem  阅读(383)  评论(0)    收藏  举报
编辑推荐:
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 长文讲解 MCP 和案例实战
· Hangfire Redis 实现秒级定时任务,使用 CQRS 实现动态执行代码
阅读排行:
· 使用TypeScript开发微信小程序(云开发)-入门篇
· 没几个人需要了解的JDK知识,我却花了3天时间研究
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 管理100个小程序-很难吗
· 在SqlSugar的开发框架中增加对低代码EAV模型(实体-属性-值)的WebAPI实现支持
< 2025年4月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10

点击右上角即可分享
微信分享提示