zoukankan      html  css  js  c++  java
  • Crash的旅行计划

    除草了。。

    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 ", 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 ", tmp);

          }

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

          {

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

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

    fprintf(outfile, "%d %d ", 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 ", 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 ", now % N + 1, tmp);

              }

          }

    fprintf(outfile, "Done ");

      }

     

    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
    ", 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
    ", 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
    ", 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;
    }
    
  • 相关阅读:
    【HDOJ】4347 The Closest M Points
    【HDOJ】4341 Gold miner
    【HDOJ】4333 Revolving Digits
    【HDOJ】4336 Card Collector
    【HDOJ】4328 Cut the cake
    【HDOJ】4322 Candy
    【HDOJ】4317 Unfair Nim
    串口接收线程退出与优先级问题
    EVC编程与调试过程出现的问题
    Windows CE创建桌面快捷方式
  • 原文地址:https://www.cnblogs.com/hsuppr/p/3277825.html
Copyright © 2011-2022 走看看