【CF1023D】Array Restoration(构造,线段树)

题意:有一个长为n的序列,对其进行q次操作,第i次操作可以把连续的一段覆盖为i

现在给出操作后的序列,第i个数字为a[i],其中有一些为0的位置可以为任意值,要求构造任意一组合法的操作后的序列

无解输出NO

n,q<=2e5,0<=a[i]<=q

思路:看不懂别人写的题解,照自己的思路写一个……

首先将a[i]从大到小排序,若a[i]已经确定则将a[i]填到i左右两端连续的0中

然后判断q有没有在填完之后的序列中出现,若没有出现则找一段连续的0覆盖成q,找不到0则无解

前面两步能将数列填满,预处理出填完之后数列中每个数值出现的第一次和最后一次出现的位置,如果中间有比他小的数字则不合法

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 #include<bitset>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef unsigned int uint;
 15 typedef unsigned long long ull;
 16 typedef pair<int,int> PII;
 17 typedef vector<int> VI;
 18 #define fi first
 19 #define se second 
 20 #define MP make_pair
 21 #define N      210000
 22 #define M      51
 23 #define MOD 1000000007
 24 #define eps 1e-8 
 25 #define pi     acos(-1)
 26 #define oo     1e9
 27 
 28 struct node
 29 {
 30     int x,y;
 31 }b[N];
 32 
 33 int t[N<<1],a[N],c[N],l[N],r[N];
 34 
 35 bool cmp(node a,node b)
 36 {
 37     return a.x>b.x;
 38 }
 39 
 40 void pushup(int p)
 41 {
 42     t[p]=min(t[p<<1],t[p<<1|1]);
 43 }
 44 
 45 void build(int l,int r,int p)
 46 {
 47     if(l==r)
 48     {
 49         t[p]=c[l];
 50         return;
 51     } 
 52     int mid=(l+r)>>1;
 53     build(l,mid,p<<1);
 54     build(mid+1,r,p<<1|1);
 55     pushup(p);
 56 }
 57 
 58 int query(int l,int r,int x,int y,int p)
 59 {
 60     if(x<=l&&r<=y) return t[p];
 61     int mid=(l+r)>>1;
 62     int tmp=oo;
 63     if(x<=mid) tmp=min(tmp,query(l,mid,x,y,p<<1));
 64     if(y>mid) tmp=min(tmp,query(mid+1,r,x,y,p<<1|1));
 65     return tmp;
 66 }
 67 
 68 int main()
 69 { 
 70     int n,q;
 71     scanf("%d%d",&n,&q);
 72     for(int i=1;i<=n;i++) 
 73     {
 74         scanf("%d",&a[i]);
 75         b[i].x=a[i];
 76         b[i].y=i;
 77     }
 78     for(int i=1;i<=n;i++) c[i]=a[i]; 
 79     sort(b+1,b+n+1,cmp);
 80     for(int i=1;i<=n;i++)
 81      if(b[i].x)
 82      {
 83          int j=b[i].y-1;
 84         while(j>0&&c[j]==0) c[j--]=b[i].x;
 85         j=b[i].y+1;
 86         while(j<=n&&c[j]==0) c[j++]=b[i].x;
 87      }
 88     int flag=0;
 89     for(int i=1;i<=n;i++)
 90      if(c[i]==q){flag=1; break;}
 91     if(!flag)
 92     {
 93         int k=0;
 94         for(int i=1;i<=n;i++)
 95          if(!a[i]){k=i; break;}
 96         if(!k)
 97         {
 98             printf("NO
");
 99             return 0;
100         }
101          else 
102          {
103              while(k<=n&&a[k]==0) c[k++]=q;
104          }
105     }
106 
107     for(int i=1;i<=n;i++)
108     {
109         if(!l[c[i]]) l[c[i]]=i;
110         r[c[i]]=i;
111     }
112     flag=1;
113     build(1,n,1);
114     for(int i=1;i<=q;i++)
115     {
116         int t=oo;
117         if(l[i]<=r[i]&&l[i]&&r[i]) t=query(1,n,l[i],r[i],1);
118         if(t<i){flag=0; break;}
119     }
120     if(flag)
121     {
122         printf("YES
");
123         for(int i=1;i<=n;i++) printf("%d ",c[i]);
124     }
125      else printf("NO
");
126     return 0;
127 }
原文地址:https://www.cnblogs.com/myx12345/p/10077432.html