K-Bag定義為K的多個任意全排列的組合(eg:1 2 3 2 3 1 1 2 3),給定一個長為n的數組,判斷是否為K-Bag的一部分。 題解: (1≤n≤5⋅105,1≤k≤109),k<=n時,用g[i]判斷前i個數是否不相等,h[i]判斷i~n是否不相等,f[i]判斷i~i+k是否不相等,b ...
K-Bag定義為K的多個任意全排列的組合(eg:1 2 3 2 3 1 1 2 3),給定一個長為n的數組,判斷是否為K-Bag的一部分。
題解: (1≤n≤5⋅105,1≤k≤109),k<=n時,用g[i]判斷前i個數是否不相等,h[i]判斷i~n是否不相等,f[i]判斷i~i+k是否不相等,b[i]表示i出現次數,num表示當前區域出現超過1次的數的個數。
當k>n時,最多只會有兩個段(...2 3 4 / 2 1 3...),離散化後判斷。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 int const N=5e5+10; 8 int n,k; 9 bool f[N],g[N],h[N]; 10 int a[N],b[N]; 11 bool find(int s){ 12 int i; 13 for (i=s;i+k-1<=n;i+=k) 14 if (!f[i]) return false; 15 if (i<=n && !h[i]) return false; 16 return true; 17 } 18 void work(){ 19 for (int i=1;i<=n;i++){ 20 scanf("%d",&a[i]); 21 b[i]=0; 22 f[i]=false; 23 g[i]=false; //前尾碼 24 h[i]=false; 25 } 26 int num=0; 27 for (int i=1;i<=k;i++){ 28 b[a[i]]++; 29 if (b[a[i]]==2) num++; 30 if (num==0) g[i]=true; 31 } 32 if (num==0) f[1]=true; 33 for (int i=k+1;i<=n;i++){ 34 b[a[i-k]]--; 35 if (b[a[i-k]]==1) num--; 36 b[a[i]]++; 37 if (b[a[i]]==2) num++; 38 if (num==0) f[i-k+1]=true; 39 } 40 for (int i=n-k+1;i<=n;i++){ 41 b[a[i-1]]--; 42 if (b[a[i-1]]==1) num--; 43 if (num==0) h[i]=true; 44 } 45 g[0]=true; 46 for (int i=0;i<k;i++) 47 if (g[i] && find(i+1)) { 48 printf("YES\n"); 49 return; 50 } 51 printf("NO\n"); 52 } 53 void work2(){ 54 for (int i=1;i<=n;i++){ 55 scanf("%d",&a[i]); 56 b[i]=a[i]; 57 g[i]=false; 58 h[i]=false; 59 } 60 sort(b+1,b+n+1); 61 int temp=unique(b+1,b+n+1)-b-1; 62 for (int i=1;i<=n;i++){ 63 a[i]=lower_bound(b+1 , b+temp+1 , a[i]) - b; 64 } 65 for (int i=1;i<=n;i++) 66 b[i]=0; 67 int num=0; 68 for (int i=1;i<=n;i++){ 69 b[a[i]]++; 70 if (b[a[i]]==2) num++; 71 if (num==0) g[i]=true; 72 } 73 for (int i=1;i<=n;i++){ 74 b[a[i-1]]--; 75 if (b[a[i-1]]==1) num--; 76 if (num==0) h[i]=true; 77 } 78 g[0]=true; 79 h[n+1]=true; 80 for (int i=0;i<=n;i++) 81 if (h[i+1] && g[i]){ 82 printf("YES\n"); 83 return; 84 } 85 printf("NO\n"); 86 } 87 int main(){ 88 int t; 89 scanf("%d",&t); 90 while (t--){ 91 scanf("%d%d",&n,&k); //k<n 時 92 if (k<=n) work(); 93 else work2(); 94 } 95 return 0; 96 }