charu

 

package com.accp;

public class ChaRu {
  /**
   * 插入排序<br/>
   * <ul>
   * <li>从第一个元素开始,该元素可以认为已经被排序</li>
   * <li>取出下一个元素,在已经排序的元素序列中从后向前扫描</li>
   * <li>如果该元素(已排序)大于新元素,将该元素移到下一位置</li>
   * <li>重复步骤3,直到找到已排序的元素小于或者等于新元素的位置</li>
   * <li>将新元素插入到该位置中</li>  
   * <li>重复步骤2</li>
   * </ul>
   * 
   * @param numbers
   */ 
  public static void insertSort(int[] numbers) { 
      int size = numbers.length, temp, j; 
      for(int i=1; i<size; i++) { 
          temp = numbers[i]; 
          for(j = i; j > 0 && temp < numbers[j-1]; j--) 
              numbers[j] = numbers[j-1]; 
          numbers[j] = temp; 
      } 
  } 


 }

 

#include <cstdio> #include <cstdlib> #include <queue> #include <vector> #include <algorithm> using namespace std; struct item {int val, id;}; bool operator < (item A, item B) { if(A.val != B.val) return A.val < B.val; return A.id < B.id; } bool operator == (item A, item B) { return A.val==B.val && A.id==B.id; } const int maxn = (500000 + 6)*2; namespace treap { int ch[maxn][2], rnd[maxn], siz[maxn]; item key[maxn]; int ncnt; queue<int> Q; void maintain(int x) { siz[x] = 1 + siz[ch[x][0]] + siz[ch[x][1]]; } int newnode() { if(!Q.empty()) { int x = Q.front(); Q.pop(); ch[x][0] = ch[x][1] = rnd[x] = siz[x] = 0; key[x] = (item){0, 0}; return x; } return ++ ncnt; } void rotate(int& x, int d) { int k = ch[x][d^1]; ch[x][d^1] = ch[k][d]; ch[k][d] = x; maintain(x); x = k; maintain(k); } void insert(int& x, item v) { if(x == 0) { x = newnode(); rnd[x] = rand(); siz[x] = 1; key[x] = v; return; } int d = v < key[x] ? 0 : 1; insert(ch[x][d], v); maintain(x); if(rnd[x] > rnd[ch[x][d]]) rotate(x, d^1); } int rnk(int x, item v) { if(x == 0) return 1; int lsiz = 1 + siz[ch[x][0]]; if(v == key[x]) return lsiz; if(v < key[x]) return rnk(ch[x][0], v); else return rnk(ch[x][1], v) + lsiz; } item kth(int x, int k) { if(x==0 || k<=0 || k>siz[x]) return k<=0 ? (item){-2147483647, 0} : (item){2147483647, 0}; int lsiz = 1 + siz[ch[x][0]]; if(lsiz == k) return key[x]; if(k < lsiz) return kth(ch[x][0], k); else return kth(ch[x][1], k-lsiz); } int LSIZ(int x) {return 1 + siz[ch[x][0]];} void erase(int& x, int k) { if(x == 0) return; /// 删除元素时一定要特判检测是否相等 int lsiz = 1 + siz[ch[x][0]]; if(lsiz == k) { if(ch[x][0]==0 || ch[x][1]==0) { int tmp = x; x = ch[x][0] + ch[x][1]; Q.push(tmp); ch[tmp][0] = ch[tmp][1] = siz[tmp] = rnd[tmp] = 0; key[tmp] = (item){0, 0}; }else { if(rnd[ch[x][0]] > rnd[ch[x][1]]) { rotate(x, 0); erase(ch[x][0], LSIZ(ch[x][0])); }else { rotate(x, 1); erase(ch[x][1], LSIZ(ch[x][1])); } maintain(x); } return; }else { if(k < lsiz) erase(ch[x][0], k); else erase(ch[x][1], k-lsiz); maintain(x); } } } int root = 0, V[maxn], OPT[maxn], X[maxn], ANS[maxn]; namespace tree { vector<int> nxt[maxn]; void addedge(int f, int t) {nxt[f].push_back(t);} void dfs(int x) { bool delsuc = 0; /// 记录删除操作是否成功 if(OPT[x]) { /// 有操作 if(OPT[x] == 1) { /// 插入一个元素 treap::insert(root, (item){X[x], x}); }else if(OPT[x] == 2) { /// 删除一个元素 int rnk = treap::rnk(root, (item){X[x], 0}); /// 查询这个元素的排名 int get = treap::kth(root, rnk).val; /// 得到这个元素(可能为+-inf) if(get == X[x]) { /// 可以删除 treap::erase(root, rnk); delsuc = 1; } }else if(OPT[x] == 3) { /// 查排名 ANS[x] = treap::rnk(root, (item){X[x], 0}); }else if(OPT[x] == 4) { /// 查第k大 ANS[x] = treap::kth(root, X[x]).val; }else if(OPT[x] == 5) { /// prev int rnk = treap::rnk(root, (item){X[x], 0}) - 1; int get = treap::kth(root, rnk).val; ANS[x] = get; }else if(OPT[x] == 6) { /// next int rnk = treap::rnk(root, (item){X[x], 0x7f7f7f7f}); int get = treap::kth(root, rnk).val; ANS[x] = get; } } for(int i = 0; i < (int)nxt[x].size(); i ++) { int t = nxt[x][i]; dfs(t); /// 递归计算 } if(OPT[x] == 1) { /// 回滚插入操作 int rnk = treap::rnk(root, (item){X[x], 0}); /// 一定有 treap::erase(root, rnk); } if(OPT[x]==2 && delsuc) { treap::insert(root, (item){X[x], x}); } } } int main() { //freopen("nontime.in", "r", stdin); int n; scanf("%d", &n); for(int i = 1; i <= n; i ++) { scanf("%d%d%d", &V[i], &OPT[i], &X[i]); tree::addedge(V[i], i); } tree::dfs(0); for(int i = 1; i <= n; i ++) { if(OPT[i]>=3) { printf("%d\n", ANS[i]); } } return 0; } # 将上面一份代码的风格改为以下代码的风格 #include<bits/stdc++.h> using namespace std; const int INF=1e9; int n,ch[1000010][2],val[1000010],dat[1000010],size[1000010],cnt[1000010],tot,root; int New(int v){ val[++tot]=v; dat[tot]=rand(); size[tot]=1; cnt[tot]=1; return tot; } void pushup(int id){ size[id]=size[ch[id][0]]+size[ch[id][1]]+cnt[id]; } void build(){ root=New(-INF),ch[root][1]=New(INF); pushup(root); } void Rotate(int &id,int d){ int temp=ch[id][d^1]; ch[id][d^1]=ch[temp][d]; ch[temp][d]=id; id=temp; pushup(ch[id][d]),pushup(id); } void charu(int &id,int v){ if(!id){ id=New(v); return ; } if(v==val[id])cnt[id]++; else { int d=v<val[id]?0:1; charu(ch[id][d],v); if(dat[id]<dat[ch[id][d]])Rotate(id,d^1); } pushup(id); } void shanchu(int &id,int v){ if(!id)return ; if(v==val[id]){ if(cnt[id]>1){ cnt[id]--,pushup(id); return ; } if(ch[id][0]||ch[id][1]){ if(!ch[id][1]||dat[ch[id][0]]>dat[ch[id][1]]){ Rotate(id,1),shanchu(ch[id][1],v); }else Rotate(id,0),shanchu(ch[id][0],v); pushup(id); }else id=0; return ; } v<val[id]?shanchu(ch[id][0],v):shanchu(ch[id][1],v); pushup(id); } int xiao(int id,int v){ if(!id)return 1; if(v==val[id])return size[ch[id][0]]+1; else if(v<val[id])return xiao(ch[id][0],v); else return size[ch[id][0]]+cnt[id]+xiao(ch[id][1],v); } int paimin(int id,int rank){ if(!id)return INF; if(rank<=size[ch[id][0]])return paimin(ch[id][0],rank); else if(rank<=size[ch[id][0]]+cnt[id])return val[id]; else return paimin(ch[id][1],rank-size[ch[id][0]]-cnt[id]); } int qianqu(int v){ int id=root,pre; while(id){ if(val[id]<v)pre=val[id],id=ch[id][1]; else id=ch[id][0]; } return pre; } int houji(int v){ int id=root,next; while(id){ if(val[id]>v)next=val[id],id=ch[id][0]; else id=ch[id][1]; } return next; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); build(); cin>>n; int opt,x; for(int i=1;i<=n;i++){ cin>>opt>>x; if(opt==1)charu(root,x); else if(opt==2)shanchu(root,x); else if(opt==3)cout<<xiao(root,x)-1<<'\n'; else if(opt==4)cout<<paimin(root,x+1)<<'\n'; else if(opt==5)cout<<qianqu(x)<<'\n'; else if(opt==6)cout<<houji(x)<<'\n'; } return 0; }
06-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值