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;
}
posted @ 2019-03-11 00:05  风浔凌  阅读(202)  评论(0编辑  收藏  举报