码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3236:[AHOI2013]作业——题解

时间:2018-04-03 14:23:44      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:==   lov   不能   代码   gpo   数据   get   cstring   href   

https://www.lydsy.com/JudgeOnline/problem.php?id=3236 

技术分享图片

第一种做法:

建两棵主席树分别处理两个问题。

第一个问题水,第二个问题参考SPOJ3267/DQUERY:D-query

但是代码量巨大,显然不能写。

第二种做法:

参考:https://blog.csdn.net/clover_hxy/article/details/56288794

对询问离线莫队,然后莫队里面套值域分块。

……值域分块还是很好写的就不讲了。

可以看出代码量巨短。

(emmm果然数据结构学傻了想的第一种做法敲了十分钟果断弃了查题解。)

(莫队还是太菜了要多练。)

#include<stack>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1e5+5;
const int M=1e6+5;
inline int read(){
    int x=0,w=1;char ch=0;
    while(ch<0||ch>9){if(ch==-)w=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=(x<<1)+(x<<3)+ch-0;ch=getchar();}
    return x*w;
}
struct data{
    int pos,l,r,a,b;
}q[M];
int a[N],cnt[N],ans[M][2],v[N],num[N],s,n,m;
inline int bel(int x){return (x-1)/s+1;}
inline bool cmp(data a,data b){
    return bel(a.l)==bel(b.l)?a.r<b.r:a.l<b.l;
}
inline void add(int k){
    if(!cnt[k])v[bel(k)]++;
    cnt[k]++;num[bel(k)]++;
}
inline void del(int k){
    cnt[k]--;num[bel(k)]--;
    if(!cnt[k])v[bel(k)]--;
}
void query(int pos,int l,int r){
    if(bel(l)==bel(r)){
    for(int i=l;i<=r;i++){
        if(cnt[i])ans[pos][1]++,ans[pos][0]+=cnt[i];
    }
    return;
    }
    for(int i=l;i<=bel(l)*s;i++)
    if(cnt[i])ans[pos][1]++,ans[pos][0]+=cnt[i];
    for(int i=(bel(r)-1)*s+1;i<=r;i++)
    if(cnt[i])ans[pos][1]++,ans[pos][0]+=cnt[i];
    for(int i=bel(l)+1;i<=bel(r)-1;i++)
    ans[pos][1]+=v[i],ans[pos][0]+=num[i];
}
int main(){
    n=read(),m=read();
    s=sqrt(n);
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=m;i++){
    q[i].pos=i,q[i].l=read(),q[i].r=read();
    q[i].a=read(),q[i].b=read();
    }
    sort(q+1,q+m+1,cmp);
    int ql=1,qr=0;
    for(int i=1;i<=m;i++){
    while(ql<q[i].l)del(a[ql++]);
    while(ql>q[i].l)add(a[--ql]);
    while(qr<q[i].r)add(a[++qr]);
    while(qr>q[i].r)del(a[qr--]);
    query(q[i].pos,q[i].a,q[i].b);
    }
    for(int i=1;i<=m;i++){
    printf("%d %d\n",ans[i][0],ans[i][1]);
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ3236:[AHOI2013]作业——题解

标签:==   lov   不能   代码   gpo   数据   get   cstring   href   

原文地址:https://www.cnblogs.com/luyouqi233/p/8707641.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!