换个角度思考

换个角度思考

https://ac.nowcoder.com/acm/contest/275/E

题解

莫队+值域分块
把询问储存起来,然后套莫队的板子
然后每次加和减这里如果采取线段树/树状数组进行操作会T
可以改用值域分块

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=1e5+5;
struct Node
{
    int l,r;
    int x;
    int id;
}q[N];
int n,m,a[N];
int block,block2;
int res[N];
int *cnt;
int cnt2[N];

bool cmp(const Node &a,const Node &b)
{
    return (a.l/block)^(b.l/block)?a.l<b.l:(((b.l/block)&1)?a.r<b.r:a.r>b.r);
}

inline void add(int x)
{
    cnt[a[x]/block2]++;
    cnt2[a[x]]++;
}

inline void del(int x)
{
    cnt[a[x]/block2]--;
    cnt2[a[x]]--;
}

inline int ask(int x)
{
    int bk=x/block2;
    int ans=0;
    for(int i=0;i<bk;i++)
        ans+=cnt[i];
    for(int i=bk*block2;i<=x;i++)
        ans+=cnt2[i];
    return ans;
}

int main()
{
    block2=sqrt(N);
    int num=N/block2+5;
    cnt=new int[num];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",a+i);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x);
        q[i].id=i;
    }

    block=n/sqrt(m*2/3*1.0);
    sort(q+1,q+m+1,cmp);
    int l=1,r=0;
    for(int i=1;i<=m;i++)
    {
        int ql=q[i].l,qr=q[i].r;
        while(l>ql)
            add(--l);
        while(l<ql)
            del(l++);
        while(r<qr)
            add(++r);
        while(r>qr)
            del(r--);
        res[q[i].id]=ask(q[i].x);
    }
    for(int i=1;i<=m;i++)
        printf("%d\n",res[i]);
    return 0;
}

全部评论

相关推荐

06-13 15:45
辽宁大学 golang
咱就是说&nbsp;你不主动&nbsp;我也不会主动下一步hhh,急死了
恶龙战士:不建议把这种帖子发到牛客上,建议去小红书发
点赞 评论 收藏
分享
05-12 11:09
已编辑
门头沟学院 后端
已注销:没必要放这么多专业技能的描述。这些应该是默认已会的,写这么多行感觉在凑内容。项目这块感觉再包装包装吧,换个名字,虽然大家的项目基本都是网上套壳的,但是你这也太明显了。放一个业务项目,再放一个技术项目。技术项目,例如中间件的一些扩展和尝试。
点赞 评论 收藏
分享
每晚夜里独自颤抖:把华北改为华南再试一试,应该就没啥问题了。改完可能都不用投,别人主动联系了。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务