BZOJ4552 HEOI2016排序

太棒了!思路很不错。

没想到HEOID1三道线段树。

这题我们可以二分答案,将小于他的在线段树中设成0,大于他的设成1然后模拟操作复杂度O(mlog^2n)

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+10;
 4 struct node
 5 {
 6     int l,s,lz;
 7 }t[N<<2];
 8 int n,m,a[N],p;
 9 struct que
10 {
11     int f,l,r;
12 }q[N];
13 void build(int p,int l,int r)
14 {
15     if(l==r){
16         t[p].l=1;return;
17     }
18     int mid=l+r>>1;t[p].l=r-l+1;
19     build(p<<1,l,mid);build(p<<1|1,mid+1,r);
20 }
21 void pushdown(int p)
22 {
23     if(t[p].lz)
24     {
25         if(t[p].lz==1)t[p<<1].s=t[p<<1].l,t[p<<1|1].s=t[p<<1|1].l;
26         if(t[p].lz==-1)t[p<<1].s=t[p<<1|1].s=0;
27         t[p<<1].lz=t[p<<1|1].lz=t[p].lz;t[p].lz=0;
28     }
29 }
30 int query(int p,int l,int r,int L,int R)
31 {
32     if(l==L&&r==R)return t[p].s;
33     int mid=l+r>>1;pushdown(p);
34     if(mid>=R)return query(p<<1,l,mid,L,R);
35     else if(L>mid)return query(p<<1|1,mid+1,r,L,R);
36     else return query(p<<1,l,mid,L,mid)+query(p<<1|1,mid+1,r,mid+1,R);
37 }
38 void change(int p,int l,int r,int L,int R,int w)
39 {
40     if(L>R)return;
41     if(l==L&&r==R)
42     {
43         if(w)t[p].s=t[p].l,t[p].lz=1;else t[p].s=0,t[p].lz=-1;return;
44     }
45     int mid=l+r>>1;pushdown(p);
46     if(mid>=R)change(p<<1,l,mid,L,R,w);
47     else if(L>mid)change(p<<1|1,mid+1,r,L,R,w);
48     else change(p<<1,l,mid,L,mid,w),change(p<<1|1,mid+1,r,mid+1,R,w);
49     t[p].s=t[p<<1].s+t[p<<1|1].s;
50 }
51 bool check(int x)
52 {
53     for(int i=1;i<=n;++i)
54     {
55         if(a[i]<x)change(1,1,n,i,i,0);
56         else change(1,1,n,i,i,1);
57     }
58     for(int i=1;i<=m;++i)
59     {
60         int tmp=query(1,1,n,q[i].l,q[i].r);
61         if(q[i].f)
62         {
63             change(1,1,n,q[i].l,q[i].l+tmp-1,1);
64             change(1,1,n,q[i].l+tmp,q[i].r,0);
65         }
66         else
67         {
68             change(1,1,n,q[i].r-tmp+1,q[i].r,1);
69             change(1,1,n,q[i].l,q[i].r-tmp,0);
70         }
71     }
72     return query(1,1,n,p,p);
73 }
74 int main()
75 {
76     scanf("%d%d",&n,&m);
77     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
78     for(int i=1;i<=m;++i)scanf("%d%d%d",&q[i].f,&q[i].l,&q[i].r);
79     scanf("%d",&p);
80     int ans,l=1,r=n;
81     build(1,1,n);
82     while(l<=r)
83     {
84         int mid=l+r>>1;
85         if(check(mid))ans=mid,l=mid+1;
86         else r=mid-1;
87     }
88     printf("%d",ans);
89     return 0;
90 }
原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8185433.html