CF1023D Array Restoration ###K ###K //K

题目链接:https://codeforces.ml/contest/1023/problem/D

题意:给定一个数组 问能否在进行q次操作后 使得一个序列变成给定的数组 第i次操作是 选定一个区间[l,r] 使得整个区间

上的数都变成i  如果a[i]是0的话 代表可以是任何数   输出最终的序列

思路:因为操作是按顺序来的  所以数组中肯定会出现q这个数  如果没出现q 且数组中没有0 则不合法

其次  先前的数不可能插在后面的数的中间  所以预处理st表  倒序查询每个数的左边界和右边界中的最小值有没有小于i的

最后其他的0即可以变成最近的数   可以向左扫一遍 再向右扫一遍来确保所有的0都变成了附近的数

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define pb push_back
  5 const int mod=1e4;
  6 const int maxn=2e5+10;
  7 const int logn=25;
  8 int f[maxn][25];
  9 int lg2[maxn];
 10 int b[maxn];
 11 int n,q;
 12 int mp[maxn];
 13 
 14 struct ac
 15 {
 16     int l,r;
 17 };
 18 ac a[maxn];
 19 
 20 void pre()
 21 {
 22     lg2[1]=0;
 23     lg2[2]=1;
 24     for(int i=3;i<maxn;i++)
 25         lg2[i]=lg2[i/2]+1;
 26 }
 27 void make_st()
 28 {
 29     for(int j=1;j<=logn;j++)
 30         for(int i=1;i+(1<<j)-1<=n;i++)
 31             f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
 32 }
 33 
 34 int query(int x,int y)
 35 {
 36     int s=lg2[y-x+1];
 37     return min(f[x][s],f[y-(1<<s)+1][s]);
 38 }
 39 
 40 
 41 int main()
 42 {
 43     ios::sync_with_stdio(0);
 44     cin.tie(0);
 45     cin>>n>>q;
 46     pre();
 47     for(int i=0;i<maxn;i++)
 48         a[i].l=1e9,a[i].r=0;
 49     int cnt=0;
 50     int index=0;
 51     for(int i=1;i<=n;i++)
 52     {
 53         int x;
 54         cin>>x;
 55         b[i]=x;
 56         mp[x]=1;
 57         a[x].l=min(a[x].l,i);
 58         a[x].r=max(a[x].r,i);
 59         if(x==0)
 60             x=1e9,cnt++,index=i;
 61         f[i][0]=x;
 62     }
 63     make_st();
 64     int f=0;
 65     if(mp[q]==0)
 66     {
 67         if(cnt==0)
 68             f=1;
 69         else
 70         {
 71             b[index]=q;
 72         }
 73     }
 74     for(int i=q;i>=1;i--)
 75     {
 76         if(mp[i]==0)
 77             continue;
 78         int l=a[i].l,r=a[i].r;
 79         if(query(l,r)<i)
 80             f=1;
 81     }
 82     if(f)
 83         cout<<"NO"<<'\n';
 84     else
 85     {
 86         cout<<"YES"<<'\n';
 87         for(int i=2;i<=n;i++)
 88             if(b[i]==0)
 89                 b[i]=b[i-1];
 90         for(int i=n-1;i>=1;i--)
 91             if(b[i]==0)
 92                 b[i]=b[i+1];
 93         for(int i=1;i<=n;i++)
 94         {
 95             if(i!=1)
 96                 cout<<" ";
 97             cout<<b[i];
 98         }
 99         cout<<'\n';
100 
101 
102     }
103 
104 
105 
106 
107 
108 
109 
110 }
View Code
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define pi pair<int,int>
  5 #define pb push_back
  6 #define fi first
  7 #define sc second
  8 #define ull unsigned long long
  9 const int maxn=2e5+10;
 10 const int mod=1e9+7;
 11 
 12 
 13 
 14 
 15 struct ac
 16 {
 17     int l,r;
 18     int mi;
 19 };
 20 ac tr[maxn*4];
 21 
 22 int a[maxn];
 23 int n,q;
 24 
 25 void pushup(int x)
 26 {
 27     tr[x].mi=min(tr[x<<1].mi,tr[x<<1|1].mi);
 28 }
 29 
 30 void build(int x,int l,int r)
 31 {
 32     tr[x]={l,r};
 33     if(l==r)
 34     {
 35         if(!a[l]) tr[x].mi=1e9;
 36         else tr[x].mi=a[l];
 37         return;
 38     }
 39     int mid=l+r>>1;
 40     build(x<<1,l,mid);
 41     build(x<<1|1,mid+1,r);
 42     pushup(x);
 43 }
 44 
 45 int query(int x,int l,int r)
 46 {
 47     int L=tr[x].l,R=tr[x].r;
 48     if(l<=L&&R<=r) return tr[x].mi;
 49     int mid=L+R>>1;
 50     int ans=1e9;
 51     if(l<=mid) ans=query(x<<1,l,r);
 52     if(r>mid) ans=min(ans,query(x<<1|1,l,r));
 53     return ans;
 54 }
 55 
 56 
 57 
 58 pi b[maxn];
 59 
 60 int dfs1(int u)
 61 {
 62     if(u==n+1||a[u]) return a[u];
 63     a[u]=dfs1(u+1);
 64     return a[u];
 65 }
 66 
 67 int dfs2(int u)
 68 {
 69     if(u==0||a[u]) return a[u];
 70     a[u]=dfs2(u-1);
 71     return a[u];
 72 }
 73 
 74 int main()
 75 {
 76     ios::sync_with_stdio(false);
 77     cin.tie(0);
 78     cin>>n>>q;
 79     int f0=0,fq=0;
 80     for(int i=1;i<=q;i++)
 81     {
 82         b[i]={1e9,-1};
 83     }
 84     for(int i=1;i<=n;i++) cin>>a[i];
 85     for(int i=1;i<=n;i++)
 86     {
 87         if(!a[i]) f0=i;
 88         if(a[i]==q) fq=1;
 89     }
 90     if(!fq&&!f0)
 91     {
 92         cout<<"NO"<<'\n';
 93         return 0;
 94     }
 95     if(!fq)
 96     {
 97         a[f0]=q;
 98     }
 99 
100 
101     for(int i=1;i<=n;i++)
102     {
103         int x=a[i];
104         b[x].fi=min(b[x].fi,i);
105         b[x].sc=max(b[x].sc,i);
106     }
107     build(1,1,n);
108     int f=0;
109     for(int i=1;i<=n;i++)
110     {
111         if(!a[i]) continue;
112         int l=b[a[i]].fi,r=b[a[i]].sc;
113         if(query(1,l,r)<a[i]) f=1;
114 
115     }
116     if(f)
117     {
118         cout<<"NO"<<'\n';
119         return 0;
120     }
121 
122     for(int i=1;i<=n;i++)
123     {
124         if(!a[i]) dfs1(i);
125     }
126 
127     for(int i=n;i>=1;i--)
128     {
129         if(!a[i]) dfs2(i);
130     }
131 
132     cout<<"YES"<<'\n';
133     for(int i=1;i<=n;i++) cout<<a[i]<<" ";
134 
135 
136 
137 
138 
139 }
View Code

 

posted @ 2020-12-04 11:11  canwinfor  阅读(95)  评论(0)    收藏  举报