noi 2005 序列维护 sequence

从昨天晚上调到现在,终于发现问题所在了:tree[0].par被修改过,而我默认其为0.。。。。。。。。  大

 

 

/* * $File: sequence.cpp * $Date: Thu May 13 08:54:30 2010 +0800 */ #define INPUT "sequence.in" #define OUTPUT "sequence.out" #include <cstdio> #include <cassert> namespace Solve { const int SEQLEN_MAX = 4000015, TREE_SIZE = SEQLEN_MAX, INF = 1 << 30, NONE = INF; inline void swap(int &a, int &b) {a ^= b; b ^= a; a ^= b;} inline int max(int a, int b) {return a > b ? a : b;} struct Node { int left, right, par, size, key, sum, maxsum, maxsum_left, maxsum_right, relax_same, relax_rev; void do_cover(int val); void do_rev(); void apply_relax(); void update(); }; Node tree[TREE_SIZE]; int tree_root, tree_size; void rotate_left(int &root); void rotate_right(int &root); void splay(int root, int tpar); inline int& get_ref(int r) { int register p = tree[r].par; if (!p) return tree_root; if (r == tree[p].left) return tree[p].left; return tree[p].right; } int find_node(int pos); int seq[SEQLEN_MAX], nseq; int make_tree(int left, int right); void get_vtx_to_root(int pos, int len); void opt_insert(int pos); void opt_delete(int pos, int len); void opt_make_same(int pos, int len, int val); void opt_reverse(int pos, int len); int opt_get_sum(int pos, int len); int opt_get_max_sum(); void solve(FILE *fin, FILE *fout); } void Solve::solve(FILE *fin, FILE *fout) { const int BUFFER_LEN = 1024 * 1024 * 5; static char buffer[BUFFER_LEN]; char *ptr = buffer - 1, *buffer_end = buffer; #define PTR_NEXT() / { / ptr ++; / if (ptr == buffer_end) / { / ptr = buffer; / buffer_end = buffer + fread(buffer, 1, BUFFER_LEN, fin); / } / } #define READ_INT(_n_) / { / while ((*ptr < '0' || *ptr > '9') && *ptr != '-') / PTR_NEXT(); / bool _nega_ = false; / if (*ptr == '-') / { / _nega_ = true; / PTR_NEXT(); / } / int register _x_ = 0; / while (*ptr >= '0' && *ptr <= '9') / { / _x_ = _x_ * 10 + *ptr - '0'; / PTR_NEXT(); / } / if (_nega_) / _x_ = -_x_; / (_n_) = _x_; / } #define READ_STR(_s_) / { / char *_p_ = (_s_); / while ((*ptr < 'A' || *ptr > 'Z') && *ptr != '-') / PTR_NEXT(); / while ((*ptr >= 'A' && *ptr <= 'Z') || *ptr == '-') / { / *(_p_ ++) = *ptr; / PTR_NEXT(); / } / *_p_ = 0; / } tree[0].maxsum = -INF; PTR_NEXT(); int m; READ_INT(nseq); READ_INT(m); nseq += 2; seq[0] = 0; for (int i = 1; i + 1 < nseq; i ++) READ_INT(seq[i]); seq[nseq - 1] = 0; tree_root = make_tree(0, nseq - 1); while (m --) { static char cmd[100]; READ_STR(cmd); if (cmd[0] == 'I') // insert { int posi; READ_INT(posi); READ_INT(nseq); for (int i = 0; i < nseq; i ++) READ_INT(seq[i]); opt_insert(posi); } else if (cmd[0] == 'D') // delete { int posi, tot; READ_INT(posi); READ_INT(tot); opt_delete(posi, tot); } else if (cmd[0] == 'M' && cmd[2] == 'K') // make-same { int posi, tot, c; READ_INT(posi); READ_INT(tot); READ_INT(c); opt_make_same(posi, tot, c); } else if (cmd[0] == 'R') // reverse { int posi, tot; READ_INT(posi); READ_INT(tot); opt_reverse(posi, tot); } else if (cmd[0] == 'G') // get-sum { int posi, tot; READ_INT(posi); READ_INT(tot); fprintf(fout, "%d/n", opt_get_sum(posi, tot)); } else // max-sum { fprintf(fout, "%d/n", opt_get_max_sum()); } } #undef READ_STR #undef READ_INT #undef PTR_NEXT } void Solve::opt_insert(int pos) { int rnew = make_tree(0, nseq - 1); get_vtx_to_root(pos + 1, 0); int root = tree[tree_root].right; tree[root].left = rnew; tree[rnew].par = root; tree[root].size += nseq; tree[root].update(); root = tree_root; tree[root].size += nseq; tree[root].update(); } void Solve::opt_delete(int pos, int len) { get_vtx_to_root(pos, len); int root = tree[tree_root].right; tree[root].left = 0; tree[root].size -= len; tree[root].update(); root = tree_root; tree[root].size -= len; tree[root].update(); } void Solve::opt_make_same(int pos, int len, int val) { static int id; id ++; get_vtx_to_root(pos, len); int root = tree[tree[tree_root].right].left; tree[root].do_cover(val); root = tree[root].par; while (root) { tree[root].update(); root = tree[root].par; } } void Solve::opt_reverse(int pos, int len) { get_vtx_to_root(pos, len); int root = tree[tree[tree_root].right].left; tree[root].do_rev(); root = tree[root].par; while (root) { tree[root].update(); root = tree[root].par; } } int Solve::opt_get_sum(int pos, int len) { get_vtx_to_root(pos, len); return tree[tree[tree[tree_root].right].left].sum; } int Solve::opt_get_max_sum() { get_vtx_to_root(1, tree[tree_root].size - 2); return tree[tree[tree[tree_root].right].left].maxsum; } void Solve::get_vtx_to_root(int pos, int len) { int r1 = find_node(pos - 1); splay(r1, 0); int r2 = find_node(pos + len); splay(r2, r1); assert(r2 == tree[r1].right); assert(tree[tree[r2].left].size == len); assert(r1 == tree_root); } int Solve::make_tree(int left, int right) { if (left > right) return 0; int root = ++tree_size, mid = (left + right) >> 1; tree[root].key = seq[mid]; tree[tree[root].left = make_tree(left, mid - 1)].par = root; tree[tree[root].right = make_tree(mid + 1, right)].par = root; tree[root].size = right - left + 1; tree[root].relax_same = NONE; tree[root].relax_rev = 0; tree[root].update(); return root; } int Solve::find_node(int pos) { int register root = tree_root; tree[root].apply_relax(); while (1) { tree[tree[root].left].apply_relax(); tree[tree[root].right].apply_relax(); if (pos >= tree[tree[root].left].size) { pos -= tree[tree[root].left].size + 1; if (pos == -1) return root; root = tree[root].right; } else root = tree[root].left; } } void Solve::rotate_left(int &root) { int t = tree[root].right; tree[t].size = tree[root].size; tree[t].par = tree[root].par; tree[root].right = tree[t].left; tree[tree[root].right].par = root; tree[t].left = root; tree[root].par = t; tree[root].size = tree[tree[root].left].size + tree[tree[root].right].size + 1; tree[root].update(); tree[t].update(); root = t; tree[tree[t].par].update(); } void Solve::rotate_right(int &root) { int t = tree[root].left; tree[t].size = tree[root].size; tree[t].par = tree[root].par; tree[root].left = tree[t].right; tree[tree[root].left].par = root; tree[t].right = root; tree[root].par = t; tree[root].size = tree[tree[root].right].size + tree[tree[root].left].size + 1; tree[root].update(); tree[t].update(); root = t; tree[tree[t].par].update(); } void Solve::splay(int root, int tpar) { while (1) { int par = tree[root].par, parpar = tree[par].par; tree[root].update(); tree[par].update(); if (par) tree[parpar].update(); if (par == tpar) return; if (parpar == tpar) { if (root == tree[par].left) rotate_right(get_ref(par)); else rotate_left(get_ref(par)); return; } if ((root == tree[par].left) == (par == tree[parpar].left)) { int &ref = get_ref(parpar); if (root == tree[par].left) { rotate_right(ref); rotate_right(ref); } else { rotate_left(ref); rotate_left(ref); } } else { if (root == tree[par].left) { rotate_right(get_ref(par)); rotate_left(get_ref(parpar)); } else { rotate_left(get_ref(par)); rotate_right(get_ref(parpar)); } } } } void Solve::Node::apply_relax() { if (this == tree) return; if (relax_same != NONE) { tree[left].do_cover(relax_same); tree[right].do_cover(relax_same); relax_same = NONE; } if (relax_rev) { tree[left].do_rev(); tree[right].do_rev(); relax_rev = 0; } } void Solve::Node::do_cover(int val) { if (this == tree) return; key = val; sum = val * size; maxsum = max(val * size, val); maxsum_left = maxsum_right = max(val * size, 0); relax_same = val; } void Solve::Node::do_rev() { if (this == tree) return; swap(left, right); swap(maxsum_left, maxsum_right); relax_rev ^= 1; } void Solve::Node::update() { if (this == tree) return; sum = tree[left].sum + tree[right].sum + key; maxsum = max(max(tree[left].maxsum, tree[right].maxsum), tree[left].maxsum_right + tree[right].maxsum_left + key); maxsum_left = max(tree[left].maxsum_left, tree[left].sum + key + tree[right].maxsum_left); maxsum_right = max(tree[right].maxsum_right, tree[right].sum + key + tree[left].maxsum_right); } int main() { FILE *fin = fopen(INPUT, "r"), *fout = fopen(OUTPUT, "w"); Solve::solve(fin, fout); fclose(fin); fclose(fout); }

 

 

  Problem: sequence
    Point    Execution Status     Score         Time [sec]    Memory [kb] 
    1        Normal               10.000        0.006         2300        
    2        Normal               10.000        1.247         87524       
    3        Normal               10.000        0.009         2364        
    4        Normal               10.000        0.517         86148       
    5        Normal               10.000        0.203         9692        
    6        Normal               10.000        0.506         25448       
    7        Normal               10.000        0.948         57500       
    8        Normal               10.000        1.427         128632      
    9        Normal               10.000        1.210         114664      
    10       Normal               10.000        1.165         77156

你可能感兴趣的:(cmd,tree,File,delete,buffer,insert)