学习打卡第20天(补发)

昨天刷了一天 结果发现刷错网站了
我真*是个的小天才(*号省略一堆不良词汇)
我发现我刷的是ac.nowcoder.com
结果他让刷的是https://www.nowcoder.com/
我服了
这不是一个网站么?!!!
算了还是先发一个昨天刷的题吧
(题有点乱码,撮合着看)

众所周知小波很擅长排序。有一天小波想到了一个很有趣的排序题,并且小波很快就做出来了,但是他不告诉你做法,所以你需要自己做出这道题。这道题是这样的:已知一个序列A长度为n,序列第i个元素为a _i (1 \le a _i \le 10^9, \forall i \not= j满足a_i \not= a_j)a
i

(1≤a
i

≤10
9
,∀i


=j满足a
i



=a
j

),有m个操作每次操作选定区间[l,r]按照升序或者降序排序。询问一开始拍第k的元素经过m次排序后排在第几位。
输入描述:
第一行一个数T(1 \le T \le 10)T(1≤T≤10)表示一共T组数据。

每组数据第一行三个数n,m,k(1\le n,m \le 10^5,1\le k \le n)n,m,k(1≤n,m≤10
5
,1≤k≤n)表示序列长度,操作个数和询问的位置。

接下来一行n个数,表示序列。

接下来m行,每行三个数opr,l,r表示操作。

当opr=0时,对区间[l,r]升序排序的操作。

当opr=1时,对区间[l,r]降序排序的操作。
输出描述:
T行,表示答案。

对于样例第一组数据:
第一次排序后得到的序列为:[3,2,\underline{1},4,5][3,2,
1,4,5]
第二次排序后得到的序列为:[3,2,\underline{1},4,5][3,2,
1,4,5]
对于样例第二组数据:
第一次排序后得到的序列为:[2,\underline{3},4,1,5][2,
3,4,1,5]
第二次排序后得到的序列为:[2,\underline{3},1,4,5][2,
3,1,4,5]
第三次排序后得到的序列为:[\underline{3},2,1,4,5][
3,2,1,4,5]
原题链接:https://ac.nowcoder.com/acm/problem/212562
下面是我的答案:
写完心态崩了
太长了

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll input(){
    ll x=0,f=0;char ch=getchar();
    while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return f? -x:x;
} 
const int N=1e5+7; 
int t[N<<2],lazy[N<<2];
int a[N]; 
void build(int rt,int l,int r){
    lazy[rt]=0;
    if(l==r){
        t[rt]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(rt<<1,l,mid),build(rt<<1|1,mid+1,r);
    t[rt]=t[rt<<1]+t[rt<<1|1];
} 
void pushdown(int rt,int l,int r){
    if(lazy[rt]){
        lazy[rt<<1]=lazy[rt];
        lazy[rt<<1|1]=lazy[rt];
        lazy[rt]--;
        int mid=(l+r)>>1;
        t[rt<<1]=lazy[rt]*(mid-l+1);
        t[rt<<1|1]=lazy[rt]*(r-mid);
        lazy[rt]=0;
    }
}
void update(int rt,int l,int r,int ul,int ur,int x){
    if(ul>ur) return;
    if(ul<=l&&r<=ur){
        t[rt]=(r-l+1)*x;
        lazy[rt]=x+1;
        return;
    }
    pushdown(rt,l,r);
    int mid=(l+r)>>1;
    if(ul<=mid) update(rt<<1,l,mid,ul,ur,x);
    if(mid<ur) update(rt<<1|1,mid+1,r,ul,ur,x);
    t[rt]=t[rt<<1]+t[rt<<1|1];
}
 int query(int rt,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr) return t[rt];
    pushdown(rt,l,r);
    int mid=(l+r)>>1,res=0;
    if(ql<=mid) res+=query(rt<<1,l,mid,ql,qr);
    if(mid<qr) res+=query(rt<<1|1,mid+1,r,ql,qr);
    return res;
}
 int main(){
    int T=input();
    while(T--){
        int n=input(),m=input(),pos=input();
 
        for(int i=1;i<=n;i++) a[i]=input();
 
        int t=a[pos];
        for(int i=1;i<=n;i++){
            if(a[i]<=t) a[i]=0;
            else a[i]=1;
        }
        build(1,1,n);
        for(int i=1;i<=m;i++){
            int opr=input(),l=input(),r=input();
            if(opr==0){
                int mx=query(1,1,n,l,r);
                if(l<=pos&&pos<=r) pos=r-mx;
                update(1,1,n,l,r-mx,0);
                update(1,1,n,r-mx+1,r,1);
            }else{
                int mx=query(1,1,n,l,r);
                if(l<=pos&&pos<=r) pos=l+mx;
                update(1,1,n,l,l+mx-1,1);
                update(1,1,n,l+mx,r,0);
            }
        }
        cout<<pos;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值