笔记——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