1. 程式人生 > >【CF1023D】Array Restoration(構造,線段樹)

【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\n"); 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\n"); 123 for(int i=1;i<=n;i++) printf("%d ",c[i]); 124 } 125 else printf("NO\n"); 126 return 0; 127 }