除草了。。

Crash的旅行计划

【问题描述】

过不了多久,Crash就要迎来他朝思暮想的暑假。在这个暑假里,他计划着到火星上旅游。在火星上有N个旅游景点,Crash用1至N这N个正整数对这些景点标号。旅游景点之间通过双向道路相连。由于火星的环境和地球有很大的差异,建立道路的成本也相对较高。为了节约成本,只有N-1条道路连接着这些旅游景点,不过可以保证任何两个不同的旅游景点都通过路径相连。

Crash预先在互联网上查阅了这些景点的信息,根据网上的介绍,他对每个景点都有一个印象值,这个印象值为一个整数。在这个旅行中,他会选择一个景点作为旅行的开始,并沿着存在的道路到达其他景点游玩。为了使旅行不显得乏味,Crash不会经过同一个景点超过一次。Crash还给这次旅行定义了一个快乐指数,也就是他经过的所有景点的印象值之和。

不过Crash是个奇怪的小朋友,他对于景点的印象值会发生改变,并且他也没有决定好应该从哪个景点开始旅行。因此他希望你能写一个程序帮他完成一个简单的任务:根据当前他对每个景点的印象值,计算从某个景点开始旅行所能获得的最大的快乐指数。

【输入格式】

输入的第一行包含一个字符和一个正整数N,字符为ABC中的一个,用来表示这个测试数据的类型(详见下面的数据规模和约定)。

第二行包含N个用空格隔开的整数,第i个整数表示Crash对i号景点的初始印象值。

接着有N-1行,每行两个正整数a、b(1 ≤a, b≤N),表示从a号景点到b号景点有一条无向道路相连。

最后是一些指令,指令只会是以下三种格式:

1.Change ux (1 ≤u≤N)将u号景点的印象值修改为x。

2.Query u (1 ≤u≤N) 询问从u号景点开始能获得的最大的快乐指数。

3.Done收到这个指令后,你的程序应该结束。

【输出格式】

对于每条Query指令,输出对应的最大快乐指数。

【样例输入1】

A 6

6 5 -4 3 -2 1

1 2

1 3

1 4

3 5

3 6

Query 3

Query 4

Change 6 10

Query 3

Change 2 -5

Query 3

Query 4

Done

【样例输出1】

7

14

7

6

15

【样例输入2】

B 5

5 -4 3 -2 1

1 2

2 3

3 4

4 5

Query 3

Change 5 10

Query 3

Query 2

Change 2 2

Query 3

Done

【样例输出2】

4

11

7

11

【数据规模和约定】

测试数据分为ABC三类,对于所有的测试数据都满足:在任何时候一个景点印象值的绝对值不超过10000,并且输入的道路一定能满足题目描述的要求,即使得任意两个不同的景点都能通过路径相连。

对于A类数据(占20%的分数)满足:N和指令的条数都不超过1000。

对于B类数据(占40%的分数)满足:N和指令的条数都不超过100000,且输入的第i条道路,连接着i号景点和i+1号景点(详见样例2)。

对于C类数据(占40%的分数)满足:N和指令的条数都不超过100000,且任何一个景点到1号景点需要通过的道路条数不超过40。

【特别说明】

由于数据大小限制为5MB,我只好对测试时的输入文件进行压缩处理。下面的函数可以将压缩的输入文件转化为原始输入文件。(函数从infile中读入压缩的输入文件,将解压缩后的输入文件输出到outfile中)

C/C++版本:

void Uncompress(FILE *infile, FILE *outfile)

{

int N, M, L, now, A, B, Q, tmp, i;

char type = getc(infile);

fscanf(infile, "%d%d%d", &N, &M, &L);

fscanf(infile, "%d%d%d%d", &now, &A, &B, &Q);

fprintf(outfile, "%c %d\n", type, N);

for (i = 1; i <= N; i ++)

{

now = (now * A + B) % Q, tmp = now % 10000;

now = (now * A + B) % Q;

if (now * 2 < Q) tmp *= -1;

if (i < N)

fprintf(outfile, "%d ", tmp);

else

fprintf(outfile, "%d\n", tmp);

}

for (i = 1; i < N; i ++)

{

now = (now * A + B) % Q;

tmp = (i < L) ? i : L;

fprintf(outfile, "%d %d\n", i - now % tmp, i + 1);

}

for (i = 1; i < M; i ++)

{

now = (now * A + B) % Q;

if (now * 3 < Q)

{

now = (now * A + B) % Q;

fprintf(outfile, "Query %d\n", now % N + 1);

}

else

{

now = (now * A + B) % Q, tmp = now % 10000;

now = (now * A + B) % Q;

if (now * 2 < Q) tmp *= -1;

now = (now * A + B) % Q;

fprintf(outfile, "Change %d %d\n", now % N + 1, tmp);

}

}

fprintf(outfile, "Done\n");

}

Pascal版本:

procedure Uncompress(varinfile, outfile : text);

var

N, M, L, now, A, B, Q, tmp, i : longint;

ch : char;

begin

read(infile, ch, N, M, L, now, A, B, Q);

writeln(outfile, ch, ' ', N);

for i := 1 to N do

begin

now := (now * A + B) mod Q;

tmp := now mod 10000;

now := (now * A + B) mod Q;

if now * 2 < Q then tmp := -tmp;

if i < n then

write(outfile, tmp, ' ')

else

writeln(outfile, tmp);

end;

for i := 1 to N - 1 do

begin

now := (now * A + B) mod Q;

if i < L then tmp := i else tmp := L;

writeln(outfile, i - now mod tmp, ' ', i + 1);

end;

for i := 1 to M - 1 do

begin

now := (now * A + B) mod Q;

if now * 3 < Q then

begin

now := (now * A + B) mod Q;

writeln(outfile, 'Query ', now mod N + 1);

end

else

begin

now := (now * A + B) mod Q;

tmp := now mod 10000;

now := (now * A + B) mod Q;

if now * 2 < Q then tmp := -tmp;

now := (now * A + B) mod Q;

writeln(outfile, 'Change ', now mod N + 1, ' ', tmp);

end;

end;

writeln(outfile, 'Done');

end;

下面给出一个具体的例子。travel_compressed.in表示压缩的输入文件,travel.in表示解压缩后的输入文件。

travel_compressed.in

travel.in

A 5 7 3

17627 543 14278 380043

A 5

-4664 7653 -3584 -210 5852

1 2

1 3

2 4

3 5

Change 5 -3724

Query 4

Change 3 -5628

Query 2

Change 5 569

Query 5

Done

mycode:

/**
* Problem:travel
* Author:Shun Yao
* Time:2013.8.23
* Result:Accepted
* Memo:Segment-Tree, DFS
*/ #include <cstring>
#include <cstdio>
#include <climits> #define MAXN 100010 long a[MAXN]; class Edge {
public:
long v;
Edge *next;
Edge() {}
~Edge() {}
Edge(long V, Edge *ne) : v(V), next(ne) {}
} *g[MAXN]; void add(long x, long y) {
g[x] = new Edge(y, g[x]);
g[y] = new Edge(x, g[y]);
} long min(long x, long y) {
return x < y ? x : y;
}
long max(long x, long y) {
return x > y ? x : y;
}
class SegT {
public:
long v, ma, mi;
SegT *l, *r;
SegT() {}
~SegT() {}
} *root;
void build(SegT *&p, long l, long r) {
p = new SegT();
p->v = 0;
if (l == r)
p->ma = p->mi = a[l];
else {
build(p->l, l, (l + r) >> 1);
build(p->r, ((l + r) >> 1) + 1, r);
p->ma = max(p->l->ma, p->r->ma);
p->mi = min(p->l->mi, p->r->mi);
}
}
long query(SegT *&p, long l, long r, long x) {
if (l == r)
return p->ma;
if (p->v) {
p->l->v += p->v;
p->l->ma += p->v;
p->l->mi += p->v;
p->r->v += p->v;
p->r->ma += p->v;
p->r->mi += p->v;
p->v = 0;
}
if (x <= ((l + r) >> 1))
return query(p->l, l, (l + r) >> 1, x);
else
return query(p->r, ((l + r) >> 1) + 1, r, x);
}
long queryma(SegT *&p, long l, long r, long L, long R) {
if (l == L && r == R)
return p->ma;
if (p->v) {
p->l->v += p->v;
p->l->ma += p->v;
p->l->mi += p->v;
p->r->v += p->v;
p->r->ma += p->v;
p->r->mi += p->v;
p->v = 0;
}
if (R <= ((l + r) >> 1))
return queryma(p->l, l, (l + r) >> 1, L, R);
else if (L > ((l + r) >> 1))
return queryma(p->r, ((l + r) >> 1) + 1, r, L, R);
return max(queryma(p->l, l, (l + r) >> 1, L, (l + r) >> 1),
queryma(p->r, ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, R));
}
long querymi(SegT *&p, long l, long r, long L, long R) {
if (l == L && r == R)
return p->mi;
if (p->v) {
p->l->v += p->v;
p->l->ma += p->v;
p->l->mi += p->v;
p->r->v += p->v;
p->r->ma += p->v;
p->r->mi += p->v;
p->v = 0;
}
if (R <= ((l + r) >> 1))
return querymi(p->l, l, (l + r) >> 1, L, R);
else if (L > ((l + r) >> 1))
return querymi(p->r, ((l + r) >> 1) + 1, r, L, R);
return min(querymi(p->l, l, (l + r) >> 1, L, (l + r) >> 1),
querymi(p->r, ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, R));
}
void modify(SegT *&p, long l, long r, long L, long R, long v) {
if (r < L || R < l)
return;
if (l >= L && r <= R) {
p->v += v;
p->ma += v;
p->mi += v;
return;
}
if (p->v) {
p->l->v += p->v;
p->l->ma += p->v;
p->l->mi += p->v;
p->r->v += p->v;
p->r->ma += p->v;
p->r->mi += p->v;
p->v = 0;
}
modify(p->l, l, (l + r) >> 1, L, R, v);
modify(p->r, ((l + r) >> 1) + 1, r, L, R, v);
p->ma = max(p->l->ma, p->r->ma);
p->mi = min(p->l->mi, p->r->mi);
} long tot = -1, t[MAXN], b[MAXN], dfn[MAXN], dff[MAXN], fa[MAXN];
void dfs(long x) {
dfn[x] = ++tot;
t[tot] = x;
for (Edge *e = g[x]; e; e = e->next)
if (e->v != fa[x]) {
a[e->v] += a[x];
fa[e->v] = x;
dfs(e->v);
}
dff[x] = tot;
} void Uncompress(FILE *infile) {
long N, M, L, now, A, B, Q, tmp, i, j, k, ans;
char type = getc(infile);
fscanf(infile, "%ld%ld%ld", &N, &M, &L);
fscanf(infile, "%ld%ld%ld%ld", &now, &A, &B, &Q);
for (i = 1; i <= N; i ++) {
now = (now * A + B) % Q, tmp = now % 10000;
now = (now * A + B) % Q;
if (now * 2 < Q) tmp *= -1;
a[i] = tmp;
}
for (i = 1; i < N; i ++) {
now = (now * A + B) % Q;
tmp = (i < L) ? i : L;
if (type != 'B')
add(i - now % tmp, i + 1);
}
switch (type) {
case 'A':
memset(fa, 0, sizeof fa);
fa[0] = -1;
add(0, 1);
dfs(0);
a[0] = 0;
for (i = 0; i <= N; ++i)
b[i] = a[t[i]];
memcpy(a, b, sizeof a);
build(root, 0, N);
break;
case 'B':
a[0] = 0;
for (i = 1; i <= N; ++i)
a[i] += a[i - 1];
build(root, 0, N);
break;
case 'C':
memset(fa, 0, sizeof fa);
fa[0] = -1;
add(0, 1);
dfs(0);
a[0] = 0;
for (i = 1; i <= N; ++i)
b[i] = a[t[i]];
memcpy(a, b, sizeof a);
build(root, 0, N);
break;
}
for (i = 1; i < M; i ++) {
now = (now * A + B) % Q;
if (now * 3 < Q) {
now = (now * A + B) % Q;
k = now % N + 1;
switch (type) {
case 'A':
ans = queryma(root, 0, N, dfn[k], dff[k]) - query(root, 0, N, dfn[fa[k]]);
j = query(root, 0, N, dfn[k]);
while (k > 1) {
tmp = INT_MIN;
if (dfn[fa[k]] <= dfn[k] - 1)
tmp = max(tmp, queryma(root, 0, N, dfn[fa[k]], dfn[k] - 1));
if (dff[k] + 1 <= dff[fa[k]])
tmp = max(tmp, queryma(root, 0, N, dff[k] + 1, dff[fa[k]]));
ans = max(ans, tmp + j - query(root, 0, N, dfn[fa[fa[k]]]) - query(root, 0, N, dfn[fa[k]]));
k = fa[k];
}
printf("%ld\n", ans);
break;
case 'B':
ans = query(root, 0, N, k) - querymi(root, 0, N, 0, k - 1);
if (k != N)
ans = max(ans, queryma(root, 0, N, k + 1, N) - query(root, 0, N, k - 1));
printf("%ld\n", ans);
break;
case 'C':
ans = queryma(root, 0, N, dfn[k], dff[k]) - query(root, 0, N, dfn[fa[k]]);
j = query(root, 0, N, dfn[k]);
while (k > 1) {
tmp = INT_MIN;
if (dfn[fa[k]] <= dfn[k] - 1)
tmp = max(tmp, queryma(root, 0, N, dfn[fa[k]], dfn[k] - 1));
if (dff[k] + 1 <= dff[fa[k]])
tmp = max(tmp, queryma(root, 0, N, dff[k] + 1, dff[fa[k]]));
ans = max(ans, tmp + j - query(root, 0, N, dfn[fa[fa[k]]]) - query(root, 0, N, dfn[fa[k]]));
k = fa[k];
}
printf("%ld\n", ans);
break;
}
}
else {
now = (now * A + B) % Q, tmp = now % 10000;
now = (now * A + B) % Q;
if (now * 2 < Q) tmp *= -1;
now = (now * A + B) % Q;
k = now % N + 1;
switch (type) {
case 'A':
j = query(root, 0, N, dfn[k]) - query(root, 0, N, dfn[fa[k]]);
modify(root, 0, N, dfn[k], dff[k], tmp - j);
break;
case 'B':
j = query(root, 0, N, k) - query(root, 0, N, k - 1);
modify(root, 0, N, k, N, tmp - j);
break;
case 'C':
j = query(root, 0, N, dfn[k]) - query(root, 0, N, dfn[fa[k]]);
modify(root, 0, N, dfn[k], dff[k], tmp - j);
break;
}
}
}
} int main() {
freopen("travel.in", "r", stdin);
freopen("travel.out", "w", stdout); Uncompress(stdin); fclose(stdin);
fclose(stdout);
return 0;
}

Crash的旅行计划的更多相关文章

  1. BZOJ2158 : Crash 的旅行计划

    A类数据: $n,q\leq1000$ 修改:$O(1)$直接改 查询:$O(n)$BFS B类数据: $n,q\leq100000$,保证是一条链 用线段树维护区间最大前缀.后缀和 修改:$O(\l ...

  2. 【BZOJ2117】 [2010国家集训队]Crash的旅游计划

    [BZOJ2117] [2010国家集训队]Crash的旅游计划 Description 眼看着假期就要到了,Crash由于长期切题而感到无聊了,因此他决定利用这个假期和好友陶陶一起出去旅游. Cra ...

  3. COGS 2. 旅行计划

    2. 旅行计划 ★☆   输入文件:djs.in   输出文件:djs.out   简单对比时间限制:3 s   内存限制:128 MB 过暑假了,阿杜准备出行旅游,他已经查到了某些城市的两两之间的距 ...

  4. [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树

    [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树 题目大意: 给出一个\(n(n\le10^5)\)个结点的树,每条边有 ...

  5. 【51Nod】1273 旅行计划 树上贪心

    [题目]51Nod 1273 旅行计划 [题意]给定n个点的树和出发点k,要求每次选择一个目的地旅行后返回,使得路径上未访问过的点最多(相同取编号最小),旅行后路径上所有点视为访问过,求旅行方案.\( ...

  6. 51nod 1273 旅行计划——思维题

    某个国家有N个城市,编号0 至 N-1,他们之间用N - 1条道路连接,道路是双向行驶的,沿着道路你可以到达任何一个城市.你有一个旅行计划,这个计划是从编号K的城市出发,每天到达一个你没有去过的城市, ...

  7. 洛谷P1137 旅行计划

    P1137 旅行计划 题目描述 小明要去一个国家旅游.这个国家有N个城市,编号为1-N,并且有M条道路连接着,小明准备从其中一个城市出发,并只往东走到城市i停止. 所以他就需要选择最先到达的城市,并制 ...

  8. 洛谷 P1137 旅行计划

    旅行计划 待证明这样dp的正确性. #include <iostream> #include <cstdio> #include <cstring> #includ ...

  9. 51nod-1273: 旅行计划

    [传送门:51nod-1273] 简要题意: 给出一棵树,点数为n,现在你有一个旅行计划,从k城市出发,每天前往一个没去过的城市,并且旅途中经过的没有去过的城市尽可能的多(如果有2条路线,经过的没有去 ...

随机推荐

  1. SQL Server 2008 设计与实现笔记(一)

    Chart5 create database MovieRental; select name, SUSER_SNAME(sid) as [login] from sys.database_princ ...

  2. 让wordpress投稿作者在后台只看到自己的文章

    wordpress支持多作者撰写,让更多的人参与网站内容的创建是个不错的想法,UGC(User-generated content)使网站主题更丰富,不同的内容吸引不同的受众,一个好的网站应该多产生U ...

  3. 论MOBA类游戏五号位的重要性

    观众朋友们,也许你对题目很好奇,才打开这篇文章.为什么技术圈中会出现游戏类的软文?如果时间充足,可以继续往下看. MOBA 类游戏的兴起,逐渐吞噬游戏市场,以病毒式的扩张方式肆意改变着游戏玩家内心对游 ...

  4. Maven的Dependency怎么找?

    用了Maven,所需的JAR包就不能再像往常一样,自己找到并下载下来,用IDE导进去就完事了,Maven用了一个项目依赖(Dependency)的概念,用俗话说,就是我的项目需要用你这个jar包,就称 ...

  5. cocos2d-x3.9 NDK android 环境搭建过程中遇到的错误

    编译环境:Mac OS, NDK r9d 错误:arm-linux-androideabi-gcc: error trying to exec '/media/Project/adt-bundle-l ...

  6. Apache Tomcat下载、安装、配置图文教程

    本文已迁移到我的个人网站 http://www.wshunli.com 文章地址: http://www.wshunli.com/2016/03/19/Tomcat安装配置/ (整理截图.安装过程更加 ...

  7. CheckBoxList 获取与设置选中的值

    /// <summary> ///CheckBoxListHelper 的摘要说明 ///CheckBoxList获取与设置选中的值 /// </summary> public ...

  8. Android tab_Host页面跳转,传值,刷新等问题汇总

    之前做了一个项目是关于Tab_Host的,现在完成了恰逢闲余写份总结,主要涉及里面遇到问题以及解决方案的. (首先说明这份代码是在eoe 下载的,这里感谢分享的那位朋友,限于我的工程是公司的不能拿出来 ...

  9. !! Scrum之 流程和术语

    !!Scrum之 流程和术语 http://www.cnblogs.com/zhoujg/archive/2009/07/15/1523680.html 以下将对一些术语进行简单介绍,以便大家现在开始 ...

  10. 约瑟夫环问题-循环链表VS数组

    2013-08-18 21:27:50 循环链表.数组解决约瑟夫环问题的比较 注意几点: 循环链表的建立不难,在删除循环链表中元素时,用pCur->next != pCur判断结束: 每一轮计数 ...