HEOI2016/TJOI2016 排序
题目链接:戳我
先贴一个可以获得80pts的代码——(你们说如果加上fread会不会更快啊qwqwq,不过我没有用。。。。。。)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
int n,m,q;
int a[MAXN],cur[MAXN];
inline bool cmp(int x,int y){return x>y;}
inline void solve1(int x,int y)
{
int cnt=0;
for(int i=x;i<=y;i++)
cur[++cnt]=a[i];
sort(&cur[1],&cur[cnt+1]);
for(int i=x;i<=y;i++)
a[i]=cur[i-x+1];
}
inline void solve2(int x,int y)
{
int cnt=0;
for(int i=x;i<=y;i++)
cur[++cnt]=a[i];
sort(&cur[1],&cur[cnt+1],cmp);
for(int i=x;i<=y;i++)
a[i]=cur[i-x+1];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=m;i++)
{
int op=read(),l=read(),r=read();
if(op==0) solve1(l,r);
else solve2(l,r);
}
q=read();
printf("%d\n",a[q]);
return 0;
}
满分代码是考虑二分——因为是全排列,所以枚举一个数。比他大的设为1,其余的设为0。然后重构一编,如果最后在他位置上的是1,那么l=mid+1,否则r=mid;
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define MAXN 100010
using namespace std;
int n,m,q;
int a[MAXN],w[MAXN];
struct Node{int l,r,sum,tag;}t[MAXN<<2];
struct Node2{int op,l,r;}node[MAXN];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void push_up(int x){t[x].sum=t[ls(x)].sum+t[rs(x)].sum;}
inline void push_down(int x)
{
if(t[x].tag==0)
{
t[ls(x)].sum=t[rs(x)].sum=0;
t[ls(x)].tag=t[rs(x)].tag=0;
}
else if(t[x].tag==1)
{
t[ls(x)].sum=t[ls(x)].r-t[ls(x)].l+1;
t[rs(x)].sum=t[rs(x)].r-t[rs(x)].l+1;
t[ls(x)].tag=t[rs(x)].tag=1;
}
t[x].tag=-1;
}
inline void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;t[x].tag=-1;
if(l==r)
{
t[x].sum=a[l];
return;
}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
}
inline void update(int x,int ll,int rr,int k)
{
int l=t[x].l,r=t[x].r;
if(ll<=l&&r<=rr)
{
t[x].tag=k;
t[x].sum=(r-l+1)*k;
return;
}
int mid=(l+r)>>1;
push_down(x);
if(ll<=mid) update(ls(x),ll,rr,k);
if(mid<rr) update(rs(x),ll,rr,k);
push_up(x);
}
inline int query(int x,int ll,int rr)
{
int l=t[x].l,r=t[x].r;
if(ll<=l&&r<=rr) return t[x].sum;
int mid=(l+r)>>1;
push_down(x);
int cur_ans=0;
if(ll<=mid) cur_ans+=query(ls(x),ll,rr);
if(mid<rr) cur_ans+=query(rs(x),ll,rr);
return cur_ans;
}
inline void solve(int x,int l,int r)
{
if(l==r) return;
int mid=(l+r)>>1;
solve(ls(x),l,mid);
solve(rs(x),mid+1,r);
}
inline bool check(int x)
{
for(int i=1;i<=n;i++)
{
if(w[i]>=x) a[i]=1;
else a[i]=0;
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int cur=query(1,node[i].l,node[i].r);
if(node[i].op==0)
{
if(cur!=0) update(1,node[i].l,node[i].r-cur,0);
if(cur!=node[i].r-node[i].l+1) update(1,node[i].r-cur+1,node[i].r,1);
}
else
{
if(cur!=0) update(1,node[i].l,node[i].l+cur-1,1);
if(cur!=node[i].r-node[i].l+1) update(1,node[i].l+cur,node[i].r,0);
}
}
return query(1,q,q);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&node[i].op,&node[i].l,&node[i].r);
scanf("%d",&q);
int l=1,r=n,ans=0;
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid;
}
printf("%d\n",ans);
return 0;
}