COGS 723. [SDOI2007] 超级数组

                  ★★☆   输入文件:arr.in   输出文件:arr.out   简单对比
                      时间限制:1 s   内存限制:3 MB

                      Source: SDOI2007 Day2
【问题描述】

一般的数组大家都经常使用,相信很多同学没有见过下面的超级数组。

超级数组存储的是一些正整数,它还支持下面的两个操作

(1)、插入一个元素,命令是 "i key" 。 key 是要插入的数。

(2)、输出第 k 大元素并删除该元素,命令是 "d k"。输出第 k 大元素并删除它。

“第 k 大”是指:现有的数中,如果从小到大排好序,从最小的开始作为第一大算起,

一直数到第 k 个。

现在给出一个开始是空的超级数组,请维护好该数组

【输入】(arr.in)

第一行 n、m:n<=1 000 000 000 , m<=100 000。表示插入数的范围是 1 至n ,共有m 条命令(包括插入和删除)。

以下 m 行,每行一条命令,如题中描述。每条命令中字母和后面的数字之间一个空格。

保证输入数据是正确的,删除的数一定存在。

【输出】(arr.out)

对于每个删除命令,按删除命令顺序输出删除的数,每个数一行

【样例输入】

100 10

i 57

i 99

i 65

d 3

i 89

d 2

d 2

d 1

i 93

i 29

【样例输出】

99

65

89

57

SBT模板题。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<cstring>
  7 #include<queue>
  8 #include<vector>
  9 using namespace std;
 10 const int maxn=100001;
 11 int key[maxn],siz[maxn],lc[maxn],rc[maxn];
 12 int root,tot;
 13 int N,M;
 14 char s[5];
 15 void r_rotate(int &rt){
 16     int k=lc[rt];
 17     lc[rt]=rc[k];
 18     rc[k]=rt;
 19     siz[k]=siz[rt];
 20     siz[rt]=siz[lc[rt]]+siz[rc[rt]]+1;
 21     rt=k;
 22 }
 23 void l_rotate(int &rt){
 24     int k=rc[rt];
 25     rc[rt]=lc[k];
 26     lc[k]=rt;
 27     siz[k]=siz[rt];
 28     siz[rt]=siz[lc[rt]]+siz[rc[rt]]+1;
 29     rt=k;
 30 }
 31 void Maintain(int &rt,bool flag){
 32     if(flag==false){
 33         if(siz[lc[lc[rt]]]>siz[rc[rt]]) r_rotate(rt);
 34         else if(siz[rc[lc[rt]]]>siz[rc[rt]]){
 35             l_rotate(lc[rt]);
 36             r_rotate(rt);
 37         }
 38         else return ;
 39     }
 40     else{
 41         if(siz[rc[rc[rt]]]>siz[lc[rt]]) l_rotate(rt);
 42         else if(siz[lc[rc[rt]]]>siz[lc[rt]]){
 43             r_rotate(rc[rt]);
 44             l_rotate(rt);
 45         }
 46         else return ;
 47     }
 48     Maintain(lc[rt],false); Maintain(rc[rt],true);
 49     Maintain(rt,false); Maintain(rt,true);
 50 }
 51 void insert(int &rt,int v){
 52     if(rt==0){
 53         rt=++tot;
 54         key[rt]=v;
 55         siz[rt]=1; lc[rt]=rc[rt]=0;
 56         return ;
 57     }
 58     siz[rt]++;
 59     if(v<=key[rt]) insert(lc[rt],v);
 60     else insert(rc[rt],v);
 61     Maintain(rt,false); Maintain(rt,true);
 62 }
 63 int Delete(int &rt,int v){
 64     int ans;
 65     siz[rt]--;
 66     if(v==key[rt]||(v<key[rt]&&lc[rt]==0)||(v>key[rt]&&rc[rt]==0)){
 67         ans=key[rt];
 68         if(lc[rt]==0||rc[rt]==0) rt=lc[rt]+rc[rt];
 69         else key[rt]=Delete(lc[rt],key[rt]+1);
 70         return ans;
 71     }
 72     if(v<key[rt]) ans=Delete(lc[rt],v);
 73     else ans=Delete(rc[rt],v);
 74     return ans;
 75 }
 76 bool find(int &rt,int v){
 77     if(rt==0) return false;
 78     if(v==key[rt]) return true;
 79     if(v<key[rt]) return find(lc[rt],v);
 80     if(v>key[rt]) return find(rc[rt],v);
 81 }
 82 int select(int &rt,int v){
 83     if(v==siz[lc[rt]]+1) return key[rt];
 84     else if(v<siz[lc[rt]]+1) return select(lc[rt],v);
 85     else return select(rc[rt],v-siz[lc[rt]]-1);
 86 }
 87 int main(){
 88     freopen("arr.in","r",stdin);
 89     freopen("arr.out","w",stdout);
 90     scanf("%d%d",&N,&M);
 91     for(int i=1,tmp;i<=M;i++){
 92         scanf("%s%d",s,&tmp);
 93         if(s[0]=='i') insert(root,tmp);
 94         else{
 95             int ans=select(root,tmp);
 96             printf("%d\n",ans);
 97             Delete(root,ans);
 98         }
 99     }
100     return 0;
101 }

转载于:https://www.cnblogs.com/CXCXCXC/p/5134294.html

以下是将代码修改为cot平滑的方法: 1. 首先,需要使用边界角的cot权重计算每个顶点的权重。 2. 然后,使用cot权重对每个顶点的邻域点进行加权计算,得到平滑后的坐标。 3. 最后,根据平滑后的坐标更新每个顶点的位置。 修改后的代码如下: float smooth() { float err = -1; cogs.clear(); v_end = mesh.vertices_end(); //cot平滑 for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) { cog[0] = cog[1] = cog[2] = weight_sum = 0.0; for (vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) { double cot_weight = 0.0; MyMesh::HalfedgeHandle heh = mesh.find_halfedge(*v_it, *vv_it); if (!mesh.is_boundary(heh)) { MyMesh::HalfedgeHandle prev_heh = mesh.prev_halfedge_handle(heh); MyMesh::HalfedgeHandle next_heh = mesh.next_halfedge_handle(heh); MyMesh::VertexHandle prev_vh = mesh.to_vertex_handle(prev_heh); MyMesh::VertexHandle next_vh = mesh.to_vertex_handle(next_heh); MyMesh::Point prev_p = mesh.point(prev_vh); MyMesh::Point curr_p = mesh.point(*v_it); MyMesh::Point next_p = mesh.point(next_vh); double cot_alpha = cot(prev_p - curr_p, next_p - curr_p); double cot_beta = cot(curr_p - prev_p, next_p - prev_p); cot_weight = cot_alpha + cot_beta; } cog += cot_weight * mesh.point(*vv_it); weight_sum += cot_weight; } cogs.push_back(cog / weight_sum); } for (v_it = mesh.vertices_begin(), cog_it = cogs.begin(); v_it != v_end; ++v_it, ++cog_it) { if (!mesh.is_boundary(*v_it)) { MyMesh::Point p = mesh.point(*v_it); err = max(err, (p - *cog_it).norm()); mesh.set_point(*v_it, *cog_it); } } return err; } 其中cot函数的定义如下: double cot(MyMesh::Point a, MyMesh::Point b) { return dot(a, b) / cross(a, b).norm(); } 注意,这里使用的是边界角的cot权重,因此在计算cot权重时需要判断当前边是否为边界。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值