Untitled
unknown
c_cpp
a year ago
6.9 kB
3
Indexable
Never
#include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAXN 300005 int n,m,COLOR_HASH[MAXN],HASH[MAXN], color_cnt, color_sorted[MAXN] ,Num[MAXN], color_cnt; const int inf=INT_MAX; typedef struct Node{ int val, size, cnt, w, color,idx; struct Node *l, *r; } Node; Node *new_node(int x,int color,int idx){ Node* node = (Node*) malloc(sizeof(Node)); node->val=x; node->color=color; node->idx=idx; node->size=1; node->cnt=1; node->w=rand(); node->l=NULL; node->r=NULL; return node; } void update_son(Node* node){ node->size=node->cnt; if(node->l != NULL) node->size+=node->l->size; if(node->r != NULL) node->size+=node->r->size; } Node *built(){ Node* rt=new_node(inf,-1,-1); rt->l=new_node(-inf,-1,-1); rt->w=-inf; rt->l->w=-inf; update_son(rt); return rt; } Node *root[MAXN], *ALL; void left_rotate(Node** a){ Node* b=(*a)->r; (*a)->r=b->l; b->l=(*a); (*a)=b; update_son((*a)); update_son((*a)->l); } void right_rotate(Node** a){ Node* b=(*a)->l; (*a)->l=b->r; b->r=(*a); (*a)=b; update_son((*a)); update_son((*a)->r); } int size(Node *node){ return node ? node->size : 0; } void insert(Node** node, int val,int color,int idx){ if(!(*node)){ (*node)=new_node(val,color,idx); return; } if(val == (*node)->val){ (*node)->cnt++; }else if(val < (*node)->val){ insert(&((*node)->l), val, color,idx); if((*node)->l->w < (*node)->w) right_rotate(node); }else{ insert(&((*node)->r), val, color,idx); if((*node)->r->w < (*node)->w) left_rotate(node); } update_son((*node)); } void del(Node** node, int val){ if (val < (*node)->val) del(&(*node)->l, val); else if ((*node)->val < val) del(&(*node)->r, val); else { if ((*node)->cnt > 1) { (*node)->cnt--; update_son((*node)); return; } if ((*node)->l == NULL && (*node)->r == NULL) { free(*node); *node = NULL; return; } if ((*node)->l == NULL) { left_rotate(node); del(&(*node)->l, val); } else if ((*node)->r == NULL) { right_rotate(node); del(&(*node)->r, val); } else { if ((*node)->l->w < (*node)->r->w) { right_rotate(node); del(&(*node)->r, val); } else { left_rotate(node); del(&(*node)->l, val); } } } update_son((*node)); } int val_to_rank(Node *node, int val){ if(val == node->val) return size(node->l) + 1; else if(val < node->val) return val_to_rank(node->l,val); else return size(node->l) + node->cnt + val_to_rank(node->r,val); } int element_color=0, element_idx=0,rank=0; int _rank_to_val(Node *node, int rank){ if(rank <= size(node->l)) return _rank_to_val(node->l,rank); else if(rank <= size(node->l) + node->cnt){ element_idx=node->idx; return node->val; }else return _rank_to_val(node->r,rank - size(node->l) - node->cnt); } int rank_to_val(Node *node, int rank){ return _rank_to_val(node,rank+1); } int suff_equal(Node* p, int val){ int suf=0; rank=0; while(p){ if(val > p->val) rank+=size(p->l)+1, p=p->r; else suf=p->val,element_color=p->color, element_idx=p->idx, p=p->l; } return suf; } int suff_bigger(Node* p, int val){ int suf=0; rank=0; while(p){ if(val >= p->val) rank+=size(p->l)+1, p=p->r; else suf=p->val, element_color=p->color, element_idx=p->idx, p=p->l; } return suf; } typedef struct Info{ int color,appetite,idx; }Info; Info info[MAXN]; int max(int a,int b){return a>b?a:b;} int min(int a,int b){return a<b?a:b;} void swap(int *a,int *b){ int tmp=*a; *a=*b; *b=tmp; } void swapInfo(Info *a,Info *b){ Info tmp=*a; *a=*b; *b=tmp; } int hash_color(int color){ int l=0,r=color_cnt-1; while(l<r){ int mid=(l+r)/2; if(color_sorted[mid]<color) l=mid+1; else r=mid; } if(color_sorted[l]!=color) return -1; return l; } void ope1(){ int color,L,R; scanf("%d %d %d",&color,&L,&R); int C=hash_color(color); if(C==-1){ printf("0\n"); return; } suff_equal(root[C],L); int lb=rank; suff_bigger(root[C],R); int rb=rank;; printf("%d\n",rb-lb); } void ope2(){ int k; scanf("%d",&k); int bigger_appe=suff_bigger(ALL, info[k].appetite); int bigger_color=element_color; int bigger_idx=element_idx; if(bigger_color==-1) return; int cur_appe=suff_equal(ALL, info[k].appetite); int cur_color=element_color; int cur_idx=element_idx; del(&ALL,cur_appe); del(&ALL,bigger_appe); insert(&ALL,bigger_appe,cur_color,cur_idx); insert(&ALL,cur_appe,bigger_color,bigger_idx); del(&root[cur_color],cur_appe); del(&root[bigger_color],bigger_appe); insert(&root[cur_color],bigger_appe,cur_color,cur_idx); insert(&root[bigger_color],cur_appe,bigger_color,bigger_idx); swap(&info[cur_idx].appetite, &info[bigger_idx].appetite); } void ope3(){ int c,d,t; scanf("%d %d %d",&c,&d,&t); c=hash_color(c); int new_val, old_val, target_idx; if(d){ //max old_val=rank_to_val(root[c],Num[c]); target_idx=element_idx; }else{ //min old_val=rank_to_val(root[c],1); target_idx=element_idx; } if(t){ //ma+1 new_val=rank_to_val(ALL,n)+1; }else{ //mi-1 new_val=rank_to_val(ALL,1)-1; } del(&root[c],old_val); insert(&root[c],new_val,c,target_idx); del(&ALL,old_val); insert(&ALL,new_val,c,target_idx); info[target_idx].appetite=new_val; } int cmp(const void *a, const void *b){ Info i=*(const Info *)a; Info j=*(const Info *)b; if(i.color!=j.color) return i.color-j.color; else return i.appetite-j.appetite; } int main(){ scanf("%d %d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&info[i].appetite); for(int i=0;i<n;i++) scanf("%d",&info[i].color), color_sorted[i]=info[i].color; qsort(color_sorted,n,sizeof(color_sorted[0]),cmp); Num[0]++; for(int i=1;i<=n;i++){ if(color_sorted[i]!=color_sorted[color_cnt]) color_cnt++; color_sorted[color_cnt]=color_sorted[i]; Num[color_cnt]++; } for(int i=0;i<color_cnt;i++) root[i]=built(); ALL=built(); for(int i=0;i<n;i++){ info[i].color=hash_color(info[i].color); insert(&root[info[i].color],info[i].appetite,info[i].color,i); insert(&ALL,info[i].appetite,info[i].color,i); } while(m--){ int x; scanf("%d",&x); if(x==1) ope1(); if(x==2) ope2(); if(x==3) ope3(); } }