zoukankan      html  css  js  c++  java
  • 洛谷 4364 [九省联考2018]IIIDX——“预留”的思路

    题目:https://www.luogu.org/problemnew/show/P4364

    原来想了一个错误的思路,就是这样:

      solve( cr , l , r ) 表示 cr 为根的子树填 [ l , r ] 的数;然后把 l 给 cr ,剩下的 [ l+1 , r ] 分成一段一段,大的段给标号小的孩子。

    然后只能得 60 分。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #define db double
    #define pb push_back
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    const int N=5e5+5;
    int n,d[N],p[N],siz[N]; db k;
    vector<int> vt[N];
    void dfs(int cr)
    {
      siz[cr]=1;
      for(int i=0,lm=vt[cr].size();i<lm;i++)
        dfs(vt[cr][i]), siz[cr]+=siz[vt[cr][i]];
    }
    void solve(int cr,int l,int r)
    {
      p[cr]=d[l]; int p0=l;
      for(int i=vt[cr].size()-1;i>=0;i--)
        {
          solve(vt[cr][i],p0+1,p0+siz[vt[cr][i]]);
          p0+=siz[vt[cr][i]];
        }
    }
    int main()
    {
      n=rdn();scanf("%lf",&k);
      for(int i=1;i<=n;i++)d[i]=rdn();
      sort(d+1,d+n+1);
      for(int i=1;i<=n;i++)
        vt[(int)floor(i/k)].pb(i);
      dfs(0); solve(0,0,n);
      for(int i=1;i<=n;i++)printf("%d ",p[i]);
      puts(""); return 0;
    }
    View Code

    看了看题解。https://files-cdn.cnblogs.com/files/NaVi-Awson/IIIDX.pdf

    关于 “去掉父亲预留的影响” ,是这样考虑:

      按顺序枚举节点,在树上就是像 bfs 一样遍历;

      一个点 cr 要预留,是为了让 “和它深度相同的点” 不要抢了它的位置。

      当开始遍历 cr 的子树的时候,直接去掉 cr 的影响并再也不加入了;这样不会有错,因为此时不会再遍历和 cr 深度相同的点了;

      下一层的点已经由它们的父亲留好了位置,所以去掉 cr 的影响也不会让之后的点出错。

    还有一种不太能理解的做法:https://www.cnblogs.com/HocRiser/p/8742680.html

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #define ls Ls[cr]
    #define rs Rs[cr]
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    int Mn(int a,int b){return a<b?a:b;}
    int Mx(int a,int b){return a>b?a:b;}
    const int N=5e5+5,M=N<<1;
    int n,a[N],fa[N],ans[N],siz[N],tp[N],tx[N];
    int tot,Ls[M],Rs[M],mn[M],tg[M];
    void pshp(int cr){mn[cr]=Mn(mn[ls],mn[rs]);}
    void build(int l,int r,int cr)
    {
      if(l==r){mn[cr]=n-l;return;}
      int mid=l+r>>1;
      ls=++tot; build(l,mid,ls);
      rs=++tot; build(mid+1,r,rs);
      pshp(cr);
    }
    void pshd(int cr)
    {
      if(!tg[cr])return; int w=tg[cr]; tg[cr]=0;
      tg[ls]+=w; tg[rs]+=w; mn[ls]+=w; mn[rs]+=w;
    }
    void mdfy(int l,int r,int cr,int L,int R,int k)
    {
      if(l>=L&&r<=R){tg[cr]+=k;mn[cr]+=k;return;}
      int mid=l+r>>1; pshd(cr);
      if(L<=mid)mdfy(l,mid,ls,L,R,k);
      if(mid<R)mdfy(mid+1,r,rs,L,R,k);
      pshp(cr);
    }
    int qry(int l,int r,int cr,int k)
    {
      if(l==r)return mn[cr]>=k?l:-1;
      int mid=l+r>>1,ret=-1; pshd(cr);
      if(mn[ls]>=k)ret=qry(mid+1,r,rs,k);
      if(ret>=0)return ret;
      return qry(l,mid,ls,k);
    }
    int main()
    {
      n=rdn(); double sl; scanf("%lf",&sl);
      for(int i=1;i<=n;i++)a[i]=rdn();
      sort(a+1,a+n+1);
      for(int i=1;i<=n;i++)tp[i]=a[i];
      int m=unique(tp+1,tp+n+1)-tp-1;
      for(int i=1;i<=n;i++)
        {
          a[i]=lower_bound(tp+1,tp+m+1,a[i])-tp;
          tx[a[i]]++;
        }
      for(int i=2;i<=m;i++)tx[i]+=tx[i-1];
      for(int i=1;i<=n;i++) fa[i]=floor(i/sl);
      for(int i=n;i;i--) siz[i]++,siz[fa[i]]+=siz[i];
      tot=1; build(0,n,1);
      for(int i=1;i<=n;i++)
        {
          if(i>1&&fa[i]!=fa[i-1])
        mdfy(0,n,1,0,ans[fa[i]]-1,siz[fa[i]]-1);
          //-1 for already use
          int p=qry(0,n,1,siz[i])+1;
          p=++tx[a[p]-1];//
          ans[i]=p;
          mdfy(0,n,1,0,p-1,-siz[i]);
        }
      for(int i=1;i<=n;i++)printf("%d ",tp[a[ans[i]]]);
      puts(""); return 0;
    }
  • 相关阅读:
    C语言运算符
    C语言的scanf函数
    C语言的数据、常量和变量
    js 操作样式属性
    点击图片显示或隐藏密码案例
    js 操作元素
    DOM 获取元素
    js 字符串对象
    js 数组
    js 倒计时 案例
  • 原文地址:https://www.cnblogs.com/Narh/p/10537426.html
Copyright © 2011-2022 走看看