小总结:

今天上午又轮到老姚出题了,老姚这次出题莫名多了一道数论(说好的不出数论呢???),还有就是一如既往的dp多,四道题里面有两道dp题目......

明天高三学长要高考了,祝愿他们能取得的一个好成绩吧(稍微带一下我呗~)

T1:精灵魔法

暑期集训第十五天(7-6)题解及总结

 

 

看到这一道题乍一看是没有什么思路的,但是详细一想,我们可以对编号进行离散化,记录一下一个人前面还有多少人编号比他大,之后以速度为基准进行排序,再数出一个点前面有多少人编号比他大,减一下就好了,原因是两个点的互换在一个点超过一个点和一个点被超过是等价的,我们只统计其中一种就可以了,这里统计的是一个点超过的点的个数,于是我们考虑从大到小枚举,把前面的点记录一下他比几个点大,之后轮到某个点之后看一下前面有几个点比他大,这样就可以统计答案了,这是什么,是区间修改,单点查询,于是选择用线段树进行维护,注意在对速度进行排序的时候要特别处理一下相等的情况,不然会100->70.

其实关于这道题的主流做法是单点修改,区间查询(和我正好相反),还可以用归并排序求逆序对,我都试着打了一下,这里就不放代码了,退一下老师的博客:https://www.cnblogs.com/hbhszxyb/p/13253975.html

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 #define debug printf("-debug-\n")
 4 #define lson (t<<1)
 5 #define rson (t<<1|1)
 6 #define mid ((l+r)>>1)
 7 using namespace std;
 8 const int N=1e6+10;
 9 struct Tree{
10     int w,lazy,siz;
11 }tree[N];
12 void pushup(int t){
13     tree[t].w=tree[lson].w+tree[rson].w;
14 }
15 void build(int t,int l,int r){
16     tree[t].siz=r-l+1;
17     if(l==r) return;
18     build(lson,l,mid);build(rson,mid+1,r);
19     pushup(t);
20 }
21 void pushdown(int t){
22     tree[lson].w+=tree[t].lazy;
23     tree[lson].lazy+=tree[t].lazy;
24     tree[rson].w+=tree[t].lazy;
25     tree[rson].lazy+=tree[t].lazy;
26     tree[t].lazy=0;
27 }
28 void change(int t,int l,int r,int cl,int cr){
29     if(cl<=l&&r<=cr){
30         tree[t].w+=tree[t].siz;
31         tree[t].lazy++;
32         return;
33     }
34     pushdown(t);
35     if(cr<=mid) change(lson,l,mid,cl,cr);
36     else if(cl>mid) change(rson,mid+1,r,cl,cr);
37     else{
38         change(lson,l,mid,cl,cr);change(rson,mid+1,r,cl,cr);
39     }
40     pushup(t);
41 }
42 int query(int t,int l,int r,int pos){
43     if(l==r){
44         return tree[t].w;
45     }
46     pushdown(t);
47     if(pos<=mid) return query(lson,l,mid,pos);
48     else return query(rson,mid+1,r,pos);
49 }
50 int ans=0,cnt=0;
51 struct Node{
52     int num,v;
53 }a[N];
54 bool cmp1(Node a,Node b){
55     return a.num<b.num;
56 }
57 bool cmp2(Node a,Node b){
58     if(a.v==b.v) return a.num<b.num;
59     return a.v<b.v;
60 }
61 signed main(){
62     int n;
63     scanf("%lld",&n);
64     build(1,1,n);
65     for(int i=1;i<=n;++i){
66         scanf("%lld",&a[i].num);
67     }
68     for(int i=1;i<=n;++i) scanf("%lld",&a[i].v);
69     sort(a+1,a+n+1,cmp1);
70     for(int i=1;i<=n;++i) a[i].num=++cnt;//离散化
71     sort(a+1,a+n+1,cmp2);
72     for(int i=n;i>=1;--i){
73         int cnt1=n-a[i].num;
74         int cnt2=query(1,1,n,a[i].num);
75         if(cnt1-cnt2>0) ans+=cnt1-cnt2;
76         if(a[i].num>1) change(1,1,n,1,a[i].num-1);
77     }
78     printf("%lld\n",ans);
79     return 0;
80 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-20
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-05
相关资源
相似解决方案