MLE求助
查看原帖
MLE求助
277023
YuanZhizheng楼主2021/4/9 21:00

我之前写了这么一段代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,k,n) for(long long i=k;i<=n;i++)
#define per(i,n,k) for(long long i=n;i>=k;i--)
#define pb push_back
#define fi first
#define se second
///#pragma GCC optimize(3,"Ofast","inline")
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef pair<ll,ll> P;
const ull mod=1e9+7;
ll gcd(ll a,ll b)
{
    ll r;
    while(b>0)
    {
        r=a%b;
        a=b;
        b=r;
    }
    return a;
}
inline void write(ll x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
inline ll read()
{
    ll x=0;
    char f=1,c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
inline ll fmul(ull a,ull b)
{
    ll ans=0;
    while(b)
    {
        if(b&1LL)
            ans=(ans+a)%mod;
        a=(a+a)%mod;
        b>>=1LL;
    }
    return ans;
}
inline ll fp(ll a,ll b)
{
    ll ans=1LL;
    while(b)
    {
        if(b&1LL)
            ans=ans*a%mod;
        a=a*a%mod;
        b>>=1LL;
    }
    return ans;
}
inline ll lcm(ll a,ll b)
{
    return a/gcd(a,b)*b;
}
const int maxn=1e7+1;
struct node
{
    int num;
}tree[maxn*8];
void update(int rt,int l,int r,int x,int add)
{
    tree[rt].num+=add;
    if(l==r)return ;
    int mid=l+r>>1;
    if(x<=mid)update(rt<<1,l,mid,x,add);
    else update(rt<<1|1,mid+1,r,x,add);
}
int Rank(int rt,int l,int r,int x)
{
    if(r<x)return tree[rt].num;
    int ans=0;
    int mid=l+r>>1;
    ans+=Rank(rt<<1,l,mid,x);
    if(mid<x-1)
        ans+=Rank(rt<<1|1,mid+1,r,x);
    return ans;
}
int Kth(int rt,int l,int r,int x)
{
    if(l==r)return l;
    int mid=l+r>>1;
    if(tree[rt<<1].num>=x)return Kth(rt<<1,l,mid,x);
    return Kth(rt<<1|1,mid+1,r,x-tree[rt<<1].num);
}
int FindPre(int rt,int l,int r,int x)
{
    if(l==r)return l;
    int mid=l+r>>1;
    if(tree[rt<<1|1].num)return FindPre(rt<<1|1,mid+1,r,x);
    return FindPre(rt<<1,l,mid,x);
}
int Pre(int rt,int l,int r,int x)
{
    if(r<x)
    {
        if(tree[rt].num)return FindPre(rt,l,r,x);
        return 0;
    }
    int mid=l+r>>1;
    int ans=0;
    if(mid<x-1&&tree[rt<<1|1].num&&(ans=Pre(rt<<1|1,mid+1,r,x)))
        return ans;
    return Pre(rt<<1,l,mid,x);
}
int FindNext(int rt,int l,int r,int x)
{
    if(l==r)return l;
    int mid=l+r>>1;
    if(tree[rt<<1].num)return FindNext(rt<<1,l,mid,x);
    return FindNext(rt<<1|1,mid+1,r,x);
}
int Next(int rt,int l,int r,int x)
{
    if(l>x)
    {
        if(tree[rt].num)return FindNext(rt,l,r,x);
        return 0;
    }
    int mid=l+r>>1;
    int ans=0;
    if(x<mid&&tree[rt<<1].num&&(ans=Next(rt<<1,l,mid,x)))
        return ans;
    return Next(rt<<1|1,mid+1,r,x);
}
int main()
{
    int inf=10000000;
    int q=read();
    while(q--)
    {
        int op=read();
        int x=read();
        if(op==1)
             update(1,-inf,inf,x,1);
        else if(op==2)
            update(1,-inf,inf,x,-1);
        else if(op==3)
            write(Rank(1,-inf,inf,x)+1),printf("\n");
        else if(op==4)
            write(Kth(1,-inf,inf,x)),printf("\n");
        else if(op==5)
            write(Pre(1,-inf,inf,x)),printf("\n");
        else write(Next(1,-inf,inf,x)),printf("\n");
    }
    return 0;
}

开的是1e7*8左右的数组,当时ac了,现在依然能ac. 现在把结构体换成了数组

#include<bits/stdc++.h>
using namespace std;
#define rep(i,k,n) for(long long i=k;i<=n;i++)
#define per(i,n,k) for(long long i=n;i>=k;i--)
#define pb push_back
#define fi first
#define se second
///#pragma GCC optimize(3,"Ofast","inline")
typedef unsigned long long ull;
//#define ll __int128
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef pair<ll,ll> pll;
inline ll gcd(ll a,ll b)
{
    while(b^=a^=b^=a%=b);
    return a;
}
inline void write(ll x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
inline ll read()
{
    ll x=0;
    char f=1,c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
inline ll fmul(ll a,ll b,ll mod)
{
    ll ans=0;
    a%=mod;
    while(b)
    {
        if(b&1LL)
            ans=(ans+a)%mod;
        a=(a+a)%mod;
        b>>=1LL;
    }
    return ans;
}
inline ll fp(ll a,ll b,ll mod)
{
    ll ans=1LL;
    a%=mod;
    while(b)
    {
        if(b&1LL)
            ans=ans*a%mod;
        a=a*a%mod;
        b>>=1LL;
    }
    return ans;
}
inline ll lcm(ll a,ll b)
{
    return a/gcd(a,b)*b;
}
const int maxn=1e7+1;
int tree[maxn<<3];
void Update(int p,int v,int rt,int l,int r)///分别代表插入的数字,加还是减,访问的节点以及节点范围
{
    tree[rt]+=v;
    if(l==r)return;
    int mid=l+r>>1;///区间中值
    if(p<=mid)Update(p,v,rt<<1,l,mid);
    else Update(p,v,rt<<1|1,mid+1,r);
}
int Rank(int x,int rt,int l,int r)///根本不需要到l==r的时候
{
    if(x>r)return tree[rt];
    int mid=l+r>>1;
    int ans=0;
    if(x>mid)ans+=Rank(x,rt<<1|1,mid+1,r);
    else ans+=Rank(x,rt<<1,l,mid);
    return ans;
}
int Kth(int x,int rt,int l,int r)///查询排名为k的数字
{
    if(l==r)return l;
    int mid=l+r>>1;
    if(x>tree[rt<<1])return Kth(x-tree[rt<<1],rt<<1|1,mid+1,r);///如果x大于左节点的数量,那么只能去右节点找剩下x-tree[rt<<1]的数字
    else return Kth(x,rt<<1,l,mid);
}
int Findpre(int rt,int l,int r)///确定区间以后就来找最大值
{
    if(l==r)return l;
    int mid=l+r>>1;
    if(tree[rt<<1|1])///去有值的节点找
        return Findpre(rt<<1|1,mid+1,r);
    return Findpre(rt<<1,l,mid);
}
int Pre(int x,int rt,int l,int r)///用来确定前驱在哪个区间里面
{
        if(r<x)///如果区间最大值小于x,那么可以在这个区间里面找最大值
        {
            if(tree[rt])return Findpre(rt,l,r);
            return 0;///如果这个区间没有值,那么直接返回就行
        }
        int mid=l+r>>1;///跟区间中值比一下大小
        if(x>mid+1&&tree[rt<<1|1])///如果大于中值,那么可以试着去右节点去找
        {
            int ans=Pre(x,rt<<1|1,mid+1,r);
            ///找第一个r<p的区间
            if(ans==0)///说明在右节点找不到那么就回左节点找
                return Pre(x,rt<<1,l,mid);
            return ans;
        }
        ///如果不满足x>mid的话,或者右节点没有数字,那么就回左节点去找
        return Pre(x,rt<<1,l,mid);
}
int Findnext(int rt,int l,int r)
{
    if(l==r)return l;
    int mid=l+r>>1;
    if(tree[rt<<1|1])return Findnext(rt<<1|1,mid+1,r);
    return Findnext(rt<<1,l,mid);
}
int Next(int x,int rt,int l,int r)///优先找小的数字
{
        if(x<l)///找到第一个这样的区间
        {
            if(tree[rt])return Findnext(rt,l,r);
            return 0;
        }
        int mid=l+r>>1;
        if(x<mid&&tree[rt<<1])
        {
            int ans=Next(x,rt<<1,l,mid);
            if(ans==0)return Next(x,rt<<1|1,mid+1,r);
            return ans;
        }
        return Next(x,rt<<1|1,mid+1,r);
}
int main()
{
        int n=read();
        for(int i=1;i<=n;i++)
        {
            int op=read();
            int x=read();
            if(op==1)Update(x,1,1,-maxn+1,maxn-1);
            else if(op==2)Update(x,-1,1,-maxn+1,maxn-1);
            else if(op==3)
            {
                printf("%d\n",Rank(x,1,-maxn+1,maxn-1)+1);
            }
            else if(op==4)
            {
                printf("%d\n",Kth(x,1,-maxn+1,maxn-1));
            }
            else if(op==5)
            {
                printf("%d\n",Pre(x,1,-maxn+1,maxn-1));
            }
            else printf("%d\n",Next(x,1,-maxn+1,maxn-1));
        }
        return 0;
}

就直接MLE,这个是怎么情况

2021/4/9 21:00
加载中...