筆記——P7910 [CSP-J 2021] 插入排序 題解


放在一切的前面:

其實,我認為——我想大家也這樣認為——這道題非常簡單,甚至有一點,(也許)十分好做,然而,我卻沒有選擇鑽研這道題,如果投入部分時間是很同意AC的——我甚至都想到了AC寫法。

正文:

思路:

思路其實很簡單,讀過題后,應當關注於這句話——

對於所有測試數據,保證在所有 Q 次操作中,至多有 5000 次操作屬於類型一

這是本題的核心——我們應該在類型一中處理,在類型2中O(1)查詢。

 

如果不···

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long n,q,a[8001];
 4 int main(){
 5 //    freopen("sort.in","r",stdin);
 6 //    freopen("sort.out","w",stdout);
 7     scanf("%lld%lld",&n,&q);
 8     for(long long i=1;i<=n;i++)
 9         scanf("%lld",&a[i]);
10     long long x;
11     for(long long i=1,ans,y,z;i<=q;i++){
12         scanf("%lld",&x);
13         if(x==1){
14             scanf("%lld%lld",&y,&z);
15             a[y]=z;
16         }
17         else{
18             ans=0;
19             scanf("%lld",&y);
20             for(int j=1;j<=n;j++){
21                 if(j<=y && a[j]<=a[y]) ans++;
22                 if(j>y && a[j]<a[y]) ans++;
23             }
24             cout<<ans<<"\n";
25         }
26     }
27     return 0;
28 }
29 //O(nQ)
76分

 

 

 

 

實現:

為了方便記錄,我們建立兩個結構體數組:

1 struct mumbers{
2     int y,z;
3 }a[30001],b[30001];
結構體建立

 

先解決類型二中的查詢:

1 if(opt==2){
2     scanf("%d",&x);
3     ans[++ans_cnt]=a[x].y;
4     continue;
5 }

 

我們來思考一些類型一:

  1. 當此數組中第 j 位在第 x 位前
  2. 當此數組中第 j 位在第 x 位后

我們根據題意,了解到我們關於處理以上兩種情況又不同的寫法,所以我們要分開討論,在此不詳述。

我們只需要一直維護 a[x].y 的值是最后的答案就可以了:

 1 scanf("%d%d",&x,&y);
 2 t=a[x].z;
 3 for(int j=1;j<=n;j++)
 4     if(j<x){
 5     if(a[j].z<=t and a[j].z>y)
 6         a[j].y++,a[x].y--;
 7     if(a[j].z>t and a[j].z<=y)
 8         a[j].y--,a[x].y++;
 9     }
10     else if(j>x){
11     if(a[j].z<t and a[j].z>=y)
12         a[j].y++,a[x].y--;
13     if(a[j].z>=t and a[j].z<y)
14         a[j].y--,a[x].y++;
15 }
16 a[x].z=y;
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,q;
 4 int ans[300001],ans_cnt;
 5 struct mumbers{
 6     int y,z;
 7 }a[30001],b[30001];
 8 bool cmp(mumbers a,mumbers b){
 9     if(a.z!=b.z) return a.z<b.z;
10     return a.y<b.y;
11 }
12 int main(){
13     scanf("%d%d",&n,&q);
14     for(int i=1,x;i<=n;i++){
15         scanf("%d",&x);
16         a[i].z=b[i].z=x;
17         b[i].y=i;
18     }
19     sort(b+1,b+n+1,cmp);
20     for(int i=1;i<=n;i++)
21         a[b[i].y].y=i;
22     for(int i=1,opt,x,y,t;i<=q;i++){
23         scanf("%d",&opt);
24         if(opt==2){
25             scanf("%d",&x);
26             ans[++ans_cnt]=a[x].y;
27             continue;
28         }
29         scanf("%d%d",&x,&y);
30         t=a[x].z;
31         for(int j=1;j<=n;j++)
32             if(j<x){
33                 if(a[j].z<=t and a[j].z>y)
34                     a[j].y++,a[x].y--;
35                 if(a[j].z>t and a[j].z<=y)
36                     a[j].y--,a[x].y++;
37             }
38             else if(j>x){
39                 if(a[j].z<t and a[j].z>=y)
40                     a[j].y++,a[x].y--;
41                 if(a[j].z>=t and a[j].z<y)
42                     a[j].y--,a[x].y++;
43             }
44         a[x].z=y;
45     }
46     for(int i=1;i<=ans_cnt;i++)
47         cout<<ans[i]<<"\n";
48     return 0;
49 }
完整代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM