最近翻了一下暑假的代码,发现了点有用的东西。
斜堆
记得是个猴子打架的题目
Code #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=100000; int f[N+10],head[N+10],lch[N+10],rch[N+10],w[N+10]; int merge(int A,int B) { if(A==0)return B; if(B==0)return A; if(w[A]<w[B])swap(A,B); rch[A]=merge(rch[A],B); swap(rch[A],lch[A]); return A; } int pop(int A){return merge(rch[A],lch[A]);} int find(int x){return f[x]==x?x:find(f[x]);} int hebing(int a,int b) { int fa=find(a),fb=find(b);f[fa]=fb; int pa=head[fa],pb=head[fb]; head[fa]=pop(head[fa]); head[fb]=pop(head[fb]); w[pa]>>=1;w[pb]>>=1; lch[pa]=0;rch[pa]=0; lch[pb]=0;rch[pb]=0; head[fa]=merge(head[fa],pa); head[fb]=merge(head[fb],pb); head[fb]=merge(head[fa],head[fb]); return fb; } int main() { int n;scanf("%d",&n); memset(lch,0,sizeof(lch)); memset(rch,0,sizeof(rch)); for(int i=1;i<=n;i++){ scanf("%d",&w[i]); f[i]=i;head[i]=i; } int m;scanf("%d",&m); for(int i=0;i<m;i++){ int a,b; scanf("%d %d",&a,&b); if(find(a)!=find(b)){ hebing(a,b); printf("%d ",w[head[find(a)]]); } else printf("-1 "); } return 0; }
支持删除和查询的排序二叉树树
为了解决约瑟夫问题转化成的数据结构问题,学长教的一个很奇怪的数据结构(其实就是平衡树的一个替代品?)
Code#include <iostream> #include <cstring> #include <cstdio> #define ll long long using namespace std; const int maxn=1000000; ll lch[maxn<<2]={0},rch[maxn<<2]={0},cnt[maxn<<2]={0},key[maxn<<2]={0}; ll top=0; bool kill[maxn<<2]={0}; int build(ll &p,ll l,ll r) { if(l>r) return 0; p=++top;ll tmp=0; key[p]=(l+r)>>1; cnt[p]=build(lch[p],l,key[p]-1); tmp =build(rch[p],key[p]+1,r); //cout<<p<<","<<l<<","<<r<<","<<key[p]<<","<<cnt[p]<<","<<tmp<<endl; return tmp+cnt[p]+1; } ll dfs(ll p,ll x) { if(p==0)return 0; ll tmp;//cout<<'*'<<key[p]<<","<<x<<endl; if((x==cnt[p])&&(!kill[key[p]])) {kill[key[p]]=1;return key[p];} if(((x<=cnt[p])&&(!kill[key[p]])||((x<cnt[p])&&(kill[key[p]])))&&(cnt[p]>0)){ tmp=dfs(lch[p],x); cnt[p]--; } else tmp=dfs(rch[p],x-cnt[p]-((!kill[key[p]])?1:0)); /* tmp=(((x<=cnt[p])&&(!kill[key[p]])||((x<cnt[p])&&(kill[key[p]])))&&(cnt[p]>0))? (dfs(lch[p],x)):(dfs(rch[p],x-cnt[p]-((!kill[key[p]])?1:0))); cnt[p]-=((x<=cnt[p])?1:0);*/ //cout<<(x<=cnt[p])<<"..."<<lch[p]<<","<<rch[p]<<","<<cnt[p]<<endl; return tmp; } long int calc(long int n,long int m,long int k) { long long root; long int ans=0,step=1; memset(kill,0,(n<<2)*sizeof(kill[0])); memset(rch,0,(n<<2)*sizeof(rch[0])); memset(lch,0,(n<<2)*sizeof(lch[0])); memset(cnt,0,(n<<2)*sizeof(cnt[0])); build(root,1,n); for(int i=0;i<k;i++){ step=((step-1+m)%(n-i)); if(step==0) step=n-i; ans=dfs(root,step-1); //cout<<(step-1+m)<<","<<step<<","<<ans<<endl; } return ans; } int main() { long int n,m,k; while(cin>>n>>m>>k) cout<<calc(n,m,k)<<endl; return 0; }