【CQOI2014】排序机械臂

    xiaoxiao2021-03-25  104

    题目

    Description

    Input

    第一行包含正整数n,表示需要排序的物品数量。

    第二行包含n个空格分隔的整数ai,表示每个物品的高度。

    Output

    输出一行包含n个空格分隔的整数pi。

    Sample Input

    输入1:

    6

    3 4 5 1 6 2

    输入2:

    4

    3 3 2 1

    Sample Output

    输出1:

    4 6 4 5 6 6

    输出2:

    4 2 4 4

    Data Constraint

    对于30%的数据 1<=n<1000

    对于100%的数据 1<=n<=100000 ,1<=ai<=2,000,000,000

    题解

    看到区间翻转就考虑到splay 其实这就是一道splay区间翻转的裸体 具体的操作都和文艺平衡树差不多,但是相较而言稍微复杂一点 需要注意的是在做findnum操作时要先pushdown一下整条路径,而不是边往根节点走边pushdown,然后仔细阅读题目后发现“相对位置不发生改变”,所以我们可以把所有的输入按照双关键字排序以确定把它们移到前面的顺序

    贴代码

    #include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<math.h> using namespace std; const int maxn=100005; int data[maxn],father[maxn],cnt[maxn],lazy[maxn]; int a[maxn][4]; int son[maxn][4]; int i,j,k,l,n,m,t1,t2,root,x,y; void qsort(int l,int r){ int i,j,mid,mid1; i=l; j=r; mid=a[(l+r)/2][1]; mid1=a[(l+r)/2][2]; while (i<=j){ while ((a[i][1]<mid)||((a[i][1]==mid)&&(a[i][2]<mid1))) i++; while ((a[j][1]>mid)||((a[j][1]==mid)&&(a[j][2]>mid1))) j--; if (i<=j){ a[0][1]=a[i][1]; a[i][1]=a[j][1]; a[j][1]=a[0][1]; a[0][2]=a[i][2]; a[i][2]=a[j][2]; a[j][2]=a[0][2]; i++; j--; } } if (i<r) qsort(i,r); if (l<j) qsort(l,j); } void pushdown(int x){ int y; if (!lazy[x]) return; y=son[x][1]; son[x][1]=son[x][2]; son[x][2]=y; if (son[x][1]) lazy[son[x][1]]^=1; if (son[x][2]) lazy[son[x][2]]^=1; lazy[x]=0; } void rotate(int x,int w){ int y; y=father[x]; cnt[y]=cnt[y]-cnt[x]+cnt[son[x][w]]; cnt[x]=cnt[x]+cnt[y]-cnt[son[x][w]]; father[x]=father[y]; if (father[y]){ if (son[father[y]][1]==y) son[father[y]][1]=x; else son[father[y]][2]=x; } son[y][3-w]=son[x][w]; if (son[x][w]) father[son[x][w]]=y; father[y]=x; son[x][w]=y; } void splay(int x){ int y; pushdown(x); while (father[x]){ y=father[x]; if (!father[y]) pushdown(father[y]); pushdown(y); pushdown(x); if (y==root){ if (son[y][1]==x) rotate(x,2); else rotate(x,1); } else{ if (y==son[father[y]][1]){ if (son[y][1]==x) {rotate(y,2); rotate(x,2);} else{rotate(x,1); rotate(x,2);} } else{ if (son[y][1]==x){rotate(x,2); rotate(x,1);} else{rotate(y,1); rotate(x,1);} } } } root=x; } int kth(int x,int w){ int i; int tmp; tmp=x; i=root; pushdown(i); while ((x!=cnt[son[i][w]]+1) && (i)){ if (x<cnt[son[i][w]]+1) i=son[i][w]; else{ x=x-cnt[son[i][w]]-1; i=son[i][3-w]; } pushdown(i); } splay(i); return i; } void dfs(int x){ if (father[x]) dfs(father[x]); pushdown(x); } int findnum(int x){ int ans; //pushdown(x); ans=cnt[son[x][1]]; while (father[x]) { //pushdown(father[x]); if (son[father[x]][2]==x) ans+=cnt[son[father[x]][1]]+1; x=father[x]; } return ans; } int main(){ //freopen("3599.in","r",stdin); //freopen("3599.out","w",stdout); scanf("%d",&n); m=n; for (i=2;i<=n+2;i++){ scanf("%d",&data[i]); father[i]=i-1; son[i-1][2]=i; cnt[i]=n-i+3; a[i-1][1]=data[i]; a[i-1][2]=i; } qsort(1,n); cnt[1]=n+2; root=1; for (i=1;i<=m;i++){ dfs(a[i][2]); printf("%d ",findnum(a[i][2])); l=kth(findnum(a[i][2])+2,1); x=kth(i,1); father[son[root][2]]=0; y=cnt[son[root][1]]; root=son[root][2]; //l=findnum(a[i][2])+2; splay(l); father[l]=x; son[x][2]=l; root=x; lazy[son[l][1]]^=1; } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-6458.html

    最新回复(0)