1 条题解

  • 0
    @ 2021-6-15 14:34:43

    C++ :

    #include <iostream>
    #include <vector>
    #include <stack>
    #include <cstdio>
    
    using namespace std;
    
    const int MAX_N = 200000;
    
    template <typename T>
    struct Node {
    	Node<T> *lson, *rson;
    	double l_rank, r_rank;
    	int size;
    	T* content;
    	Node() {
    		l_rank = 0.0;
    		r_rank = 1.0;
    		lson = rson = NULL;
    		content = NULL;
    		size = 1;
    	}
    };
    
    template <typename T>
    Node<T>* newNode() {
    	static Node<T> nodes[MAX_N+2];
    	static Node<T>* head = nodes;
    	*head = Node<T>();
    	return head++;
    }
    
    template <typename T>
    T* check(Node<T>* cur_node, T* key) {
    	if (compare(cur_node->content, key)==0)
    		return cur_node->content;
    	if (cur_node->rson==NULL) return NULL;
    	if (compare(cur_node->rson->content, key)<=0)
    		return check(cur_node->rson, key);
    	return check(cur_node->lson, key);
    }
    
    template <typename T>
    Node<T>* insert(Node<T>* cur_node, T* key) {
    	if (cur_node==NULL) {
    		cur_node = newNode<T>();
    		cur_node->content = key;
    		return cur_node;
    	}
    	if (cur_node->size==1) {
    		if (compare(cur_node->content, key)<=0) {
    			cur_node->lson = insert<T>(NULL, cur_node->content);
    			cur_node->rson = insert<T>(NULL, key);
    		} else {
    			cur_node->lson = insert<T>(NULL, key);
    			cur_node->rson = insert<T>(NULL, cur_node->content);
    		}
    		sumUp(cur_node);
    		flood_rank(cur_node, cur_node->l_rank, cur_node->r_rank);
    		return cur_node;
    	}
    	if (compare(cur_node->rson->content, key)<=0)
    		cur_node->rson = insert<T>(cur_node->rson, key);
    	else
    		cur_node->lson = insert<T>(cur_node->lson, key);
    	return sumUp(cur_node);
    }
    
    template<typename T>
    struct Iter {
    	stack<Node<T>*> state;
    	stack<Node<T>*> available;
    	Iter(Node<T>* root) {
    		state.push(root);
    	}
    	Node<T>* nxt_node() {
    		while(state.top()->size>1) {
    			available.push(state.top());
    			state.pop();
    			state.push(available.top()->rson);
    			state.push(available.top()->lson);
    		}
    		Node<T>* cur_node = state.top();
    		state.pop();
    		return cur_node;
    	}
    	Node<T>* get_available() {
    		Node<T>* cur_node = available.top();
    		available.pop();
    		return cur_node;
    	}
    };
    
    template<typename T>
    Node<T>* sumUp(Node<T>* cur_node) {
    	cur_node->size = cur_node->lson->size + cur_node->rson->size;
    	cur_node->content = cur_node->lson->content;
    	if (cur_node->lson->size<cur_node->size/3
    			|| cur_node->rson->size<cur_node->size/3) {
    		Iter<T> itr(cur_node);
    		double l_rank = cur_node->l_rank;
    		double r_rank = cur_node->r_rank;
    		cur_node = toPerfect(1, cur_node->size, itr);
    		flood_rank(cur_node, l_rank, r_rank);
    	}
    	return cur_node;
    }
    
    template<typename T>
    Node<T>* toPerfect(int l, int r, Iter<T>& itr) {
    	if (l==r) return itr.nxt_node();
    	Node<T>* lson = toPerfect(l, (l+r)/2, itr);
    	Node<T>* rson = toPerfect((l+r)/2+1, r, itr);
    	Node<T>* cur_node = itr.get_available();
    	cur_node->lson = lson;
    	cur_node->rson = rson;
    	return sumUp(cur_node);
    }
    
    template<typename T>
    void flood_rank(Node<T>* cur_node, double l, double r) {
    	if (cur_node==NULL) return;
    	cur_node->l_rank = l;
    	cur_node->r_rank = r;
    	double m = (l+r)/2.0;
    	cur_node->content->offer_rank(m);
    	flood_rank(cur_node->lson, l, m);
    	flood_rank(cur_node->rson, m, r);
    }
    
    template<typename T>
    Node<T>* erase(Node<T>* cur_node, T* key) {
    	if (cur_node->size==1) return NULL;
    	if (compare(cur_node->rson->content, key)<=0) {
    		cur_node->rson = erase(cur_node->rson, key);
    		if (!(cur_node->rson)) {
    			return cur_node->lson;
    		}
    		sumUp(cur_node);
    	} else {
    		cur_node->lson = erase(cur_node->lson, key);
    		if (!(cur_node->lson)) {
    			return cur_node->rson;
    		}
    		sumUp(cur_node);
    	}
    	return cur_node;
    }
    
    int signum(double x) {
    	return (x>0)-(x<0);
    }
    
    struct Frac {
    	int head;
    	Frac* tail;
    	double rank;
    	Frac() : rank(-1.0) {}
    	void offer_rank(double r) {
    		rank = r;
    	}
    };
    
    Frac* newFrac() {
    	static Frac fracs[MAX_N+2];
    	static Frac* head = fracs;
    	head->rank = -1.0;
    	return head++;
    }
    
    int compare(const Frac *x, const Frac *y) {
    	if (x==y) return 0;
    	if (x->rank>=0&&y->rank>=0)
    		return signum(x->rank-y->rank);
    	if (x->head!=y->head) return x->head-y->head;
    	return compare(x->tail, y->tail);
    }
    
    template <typename T>
    T* getKth(Node<T> *cur_node, int k) {
    	if (cur_node==NULL || k>=cur_node->size) return NULL;
    	if (k==0) return cur_node->content;
    	if (k<cur_node->lson->size) return getKth(cur_node->lson, k);
    	return getKth(cur_node->rson, k-cur_node->lson->size);
    }
    
    struct Score {
    	int int_part;
    	Frac *frac_part;
    	Score() : int_part(0), frac_part(NULL) {}
    };
    
    Score* newScore(int c, Score *score) {
    	static Score scores[MAX_N+2];
    	static Score *head = scores;
    	if(score==NULL) return head++;
    	head->int_part = (c+score->int_part)/2;
    	Frac* new_frac = newFrac();
    	new_frac->head = (c+score->int_part)%2;
    	new_frac->tail = score->frac_part;
    	head->frac_part = new_frac;
    	return head++;
    }
    
    int compare(Score *x, Score *y) {
    	if(x->int_part!=y->int_part)
    		return x->int_part-y->int_part;
    	return compare(x->frac_part, y->frac_part);
    }
    
    struct Movie {
    	int id, event;
    	Score *score;
    	void offer_rank(double rank) {}
    };
    
    Movie *newMovie(int id, int event, Score *score) {
    	static Movie movies[MAX_N+2];
    	static Movie *head=movies;
    	head->id = id;
    	head->event = event;
    	head->score = score;
    	return head++;
    }
    
    int compare(Movie *x, Movie *y) {
    	if(compare(x->score, y->score)!=0)
    		return -compare(x->score, y->score);
    	return x->event-y->event;
    }
    
    const int MAX_ID = 100000;
    int main() {
    //freopen("movie.in", "r", stdin);
    //freopen("movie.out", "w", stdout);
    	int q;
    	scanf("%d", &q);
    	Frac* zero = newFrac();
    	zero->head = 0;
    	zero->tail = zero;
    	Node<Frac> *root_frac = NULL;
    	root_frac = insert(root_frac, zero);
    	Node<Movie> *root_movie = NULL;
    	vector<Movie*> event_movie(MAX_ID+1);
    	event_movie[0] = newMovie(0, 0, newScore(0, NULL));
    	event_movie[0]->score->int_part = 0;
    	event_movie[0]->score->frac_part = zero;
    	vector<Movie*> id_movie(MAX_ID+1);
    	vector<int> actor_last_event(MAX_ID+1);
    	char op[3];
    	for(int event=1; event<=q; ++event) {
    		scanf("%s", op);
    		switch (op[0]) {
    			case 'R': {
    					  int id, num_actor;
    					  scanf("%d%d", &id, &num_actor);
    					  int pre_event = 0;
    					  for(int actor_id, i=0; i<num_actor; ++i) {
    						  scanf("%d", &actor_id);
    						  pre_event = max(pre_event, actor_last_event[actor_id]);
    						  actor_last_event[actor_id] = event;
    					  }
    					  event_movie[event] = newMovie(id, event, event_movie[pre_event]->score);
    					  id_movie[id] = event_movie[event];
    					  root_movie = insert(root_movie, id_movie[id]);
    					  break;
    				  }
    			case 'C': {
    					  int id, c_score;
    					  scanf("%d%d", &id, &c_score);
    					  Score *new_score = newScore(c_score, id_movie[id]->score);
    					  Frac *tmp_frac = check(root_frac, new_score->frac_part);
    					  if(tmp_frac!=NULL) new_score->frac_part = tmp_frac;
    					  else root_frac = insert(root_frac, new_score->frac_part);
    					  root_movie = erase(root_movie, id_movie[id]);
    					  id_movie[id]->score = new_score;
    					  root_movie = insert(root_movie, id_movie[id]);
    					  break;
    				  }
    			case 'Q': {
    					  int rank;
    					  scanf("%d", &rank);
    					  --rank;
    					  printf("%d\n", getKth(root_movie, rank)->id);
    					  break;
    				  }
    		}
    	}
    	return 0;
    }
    
    
    • 1

    信息

    ID
    1018
    时间
    1000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者