2018SD省隊集訓R1 D7

T1

題解:

代碼:

T2

這裏寫圖片描述

題解:

很明顯我們可以轉化一下看看,貪心的從最小的開始選擇,每一個數字可以連向左邊還沒被擴進去的最大值,右邊的第一個,或者是自己,維護區間最大值可以用線段樹,維護哪些區間被用過可以用set。

這裏寫圖片描述
則234被扎死口,234的值都是0;56未被扎死口,6的值是0。可以發現,被扎死口的元素值爲0,值爲0的元素不一定被扎死口,因爲還可以向左連5,這裏扎死口的概念就是能否越過這個點向左找值的意思

代碼:

#include <set>
#include <cstdio>
#include <iostream>
#define INF 1e9
using namespace std;
const int N=100005;
set<int>s;int maxx[N*4],a[N],pos[N],n,ans[N];
void updata(int now){maxx[now]=max(maxx[now<<1],maxx[now<<1|1]);}
void change(int now,int l,int r,int x,int v)
{
    if (l==r){maxx[now]=v;return;}
    int mid=(l+r)>>1;
    if (x<=mid) change(now<<1,l,mid,x,v);
    else change(now<<1|1,mid+1,r,x,v);
    updata(now); 
}
int qurry(int now,int l,int r,int lrange,int rrange)
{
    if (lrange>rrange) return 0;
    if (lrange<=l && rrange>=r) return maxx[now];
    int mid=(l+r)>>1,ans=0;
    if (lrange<=mid) ans=qurry(now<<1,l,mid,lrange,rrange);
    if (rrange>mid) ans=max(ans,qurry(now<<1|1,mid+1,r,lrange,rrange));
    return ans;
}
void bl(int l,int r)
{
    for (int i=l;i<=r;i++) 
      change(1,1,n,i,0),s.insert(i);
    int z=r-l+1;
    for (int i=0;i<=r-l;i++) ans[a[l+(i-1+z)%z]]=a[l+i];
}
int main()
{
    freopen("perm.in","r",stdin);
    freopen("perm.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=1;i<=n;i++) pos[a[i]]=i;
    for (int i=1;i<=n;i++) change(1,1,n,pos[i],i);
    s.insert(0);
    for (int i=1;i<=n;i++)
      if (!ans[i])
      {
        int wz=0,now=pos[i],maxx=0,zuo;
        wz=*--s.lower_bound(now);
        if (qurry(1,1,n,now,now)!=0) maxx=i,zuo=now;
        //可能已經被選了(被向右擴的結果 ,不能用s.count的原因是這個點不一定被扎死口,可能後邊的還向前連 
        //被扎死口的一定是0,0的不一定被扎死口 
        if (!s.count(now+1)) //右邊的已經被選過了
        {
            if (maxx<a[now+1]) maxx=a[now+1],zuo=now+1;
        } 
        if (wz+1<=now-1)
        {
            int z=qurry(1,1,n,wz+1,now-1);
            if (maxx<z) maxx=z,zuo=pos[z];
        }
        if (zuo==now)
        {
            s.insert(now);change(1,1,n,now,0);
            ans[i]=i;
            continue;
        }
        if (zuo==now+1)
        {
            change(1,1,n,now+1,0);
            continue;
        }
        bl(zuo,now);
      }
    for (int i=1;i<=n;i++) printf("%d ",ans[i]);
}

T3

題解:

代碼:

發佈了722 篇原創文章 · 獲贊 547 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章