首页 技术 正文
技术 2022年11月10日
0 收藏 957 点赞 3,680 浏览 4185 个字

BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块

Description

Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。为了方便,我们规定妹子们的美丽度全都在[1,n]中。给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl…sr中,权值∈[a,b]的权值的种类数。

Input

第一行包括两个整数n,m(1<=n<=100000,1<=m<=1000000),表示数列s中的元素数和询问数。第二行包括n个整数s1…sn(1<=si<=n)。接下来m行,每行包括4个整数l,r,a,b(1<=l<=r<=n,1<=a<=b<=n),意义见题目描述。保证涉及的所有数在C++的int内。保证输入合法。

Output

对每个询问,单独输出一行,表示sl…sr中权值∈[a,b]的权值的种类数。

Sample Input

10 10
4 4 5 1 4 1 5 1 2 1
5 9 1 2
3 4 7 9
4 4 2 5
2 3 4 7
5 10 4 4
3 9 1 1
1 4 5 9
8 9 3 3
2 2 1 6
8 9 1 4

Sample Output

2
0
0
2
1
1
1
0
1
2

HINT

样例的部分解释:5 9 1 2子序列为4 1 5 1 2在[1,2]里的权值有1,1,2,有2种,因此答案为2。3 4 7 9子序列为5 1在[7,9]里的权值有5,有1种,因此答案为1。4 4 2 5子序列为1没有权值在[2,5]中的,因此答案为0。2 3 4 7子序列为4 5权值在[4,7]中的有4,5,因此答案为2。建议使用输入/输出优化。 


分析:经典的莫队练习题。可以用树状数组修改,但因为修改和查询复杂度都是$O(logn)$,修改次数为$O(n\sqrt m)$,查询次数$O(m)$,总时间复杂度$O(n\sqrt m logn)$。如果把值域分块的话修改的复杂度$O(1)$,查询复杂度$O(\sqrt n)$,总时间复杂度$O(n\sqrt m)$。把询问像莫队那么搞,然后把值域分块,每个块维护块内答案,找答案时在$a\thicksim b$ 的块里面找答案。 代码(3809):

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
char nc() {
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd() {
register int x=0;
register char s=nc();
while(s<'0'||s>'9')s=nc();
while(s>='0'&&s<='9')x=(x<<3)+(x<<1)+s-'0',s=nc();
return x;
}
#define N 100001
int n,m,c[N],pos[N],L[1050],R[1050],size,block,ansblo[1050],h[N],ans[N*10];
struct A {
int l,r,a,b,id;
}q[N*10];
bool cmp(const A &x,const A &y) {
if(pos[x.l]!=pos[y.l]) return x.l<y.l;
return x.r<y.r;
}
int query(int l,int r) {
int p=pos[l],q=pos[r],ans=0,i;
if(p==q) {
for(i=l;i<=r;i++) {
if(h[i]) ans++;
}
return ans;
}
for(i=p+1;i<q;i++) {
ans+=ansblo[i];
}
for(i=l;i<=R[p];i++) {
if(h[i]) ans++;
}
for(i=L[q];i<=r;i++) {
if(h[i]) ans++;
}
return ans;
}
void del(int x) {
h[x]--;
if(h[x]==0) ansblo[pos[x]]--;
}
void add(int x) {
h[x]++;
if(h[x]==1) ansblo[pos[x]]++;
}
void solve() {
int l=1,r=0,i;
for(i=1;i<=m;i++) {
while(l<q[i].l) del(c[l]),l++;
while(r>q[i].r) del(c[r]),r--;
while(l>q[i].l) l--,add(c[l]);
while(r<q[i].r) r++,add(c[r]);
ans[q[i].id]=query(q[i].a,q[i].b);
}
}
int main() {
n=rd(); m=rd();
int i,j,size=sqrt(n);
block=n/size;
for(i=1;i<=block;i++) {
L[i]=R[i-1]+1; R[i]=size*i;
for(j=L[i];j<=R[i];j++) {
c[j]=rd(); pos[j]=i;
}
}
if(R[block]!=n) {
block++; L[block]=R[block-1]+1; R[block]=n;
for(i=L[block];i<=n;i++) {
c[i]=rd(); pos[i]=block;
}
}
for(i=1;i<=m;i++) {
q[i].l=rd(); q[i].r=rd(); q[i].a=rd(); q[i].b=rd();
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
solve();
for(i=1;i<=m;i++) {
printf("%d\n",ans[i]);
}
}

代码(3263):

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
char nc() {
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd() {
register int x=0;
register char s=nc();
while(s<'0'||s>'9')s=nc();
while(s>='0'&&s<='9')x=(x<<3)+(x<<1)+s-'0',s=nc();
return x;
}
#define N 100001
int n,m,c[N],pos[N],L[1050],R[1050],size,block,ansblo[1050],h[N],ans[N*10],ans1[N*10],ansblo1[1050];
struct A {
int l,r,a,b,id;
}q[N*10];
bool cmp(const A &x,const A &y) {
if(pos[x.l]!=pos[y.l]) return x.l<y.l;
return x.r<y.r;
}
int query(int l,int r) {
int p=pos[l],q=pos[r],ans=0,i;
if(p==q) {
for(i=l;i<=r;i++) {
if(h[i]) ans++;
}
return ans;
}
for(i=p+1;i<q;i++) {
ans+=ansblo[i];
}
for(i=l;i<=R[p];i++) {
if(h[i]) ans++;
}
for(i=L[q];i<=r;i++) {
if(h[i]) ans++;
}
return ans;
}
int query1(int l,int r) {
int p=pos[l],q=pos[r],i,ans=0;
if(p==q) {
for(i=l;i<=r;i++) {
if(h[i]) ans+=h[i];
}
return ans;
}
for(i=p+1;i<q;i++) ans+=ansblo1[i];
for(i=l;i<=R[p];i++) if(h[i]) ans+=h[i];
for(i=L[q];i<=r;i++) if(h[i]) ans+=h[i];
return ans;
}
void del(int x) {
h[x]--;
if(h[x]==0) ansblo[pos[x]]--;
ansblo1[pos[x]]--;
}
void add(int x) {
h[x]++;
if(h[x]==1) ansblo[pos[x]]++;
ansblo1[pos[x]]++;
}
void solve() {
int l=1,r=0,i;
for(i=1;i<=m;i++) {
while(l<q[i].l) del(c[l]),l++;
while(r>q[i].r) del(c[r]),r--;
while(l>q[i].l) l--,add(c[l]);
while(r<q[i].r) r++,add(c[r]);
ans[q[i].id]=query(q[i].a,q[i].b);
ans1[q[i].id]=query1(q[i].a,q[i].b);
}
}
int main() {
n=rd(); m=rd();
int i,j,size=sqrt(n);
block=n/size;
for(i=1;i<=block;i++) {
L[i]=R[i-1]+1; R[i]=size*i;
for(j=L[i];j<=R[i];j++) {
c[j]=rd(); pos[j]=i;
}
}
if(R[block]!=n) {
block++; L[block]=R[block-1]+1; R[block]=n;
for(i=L[block];i<=n;i++) {
c[i]=rd(); pos[i]=block;
}
}
for(i=1;i<=m;i++) {
q[i].l=rd(); q[i].r=rd(); q[i].a=rd(); q[i].b=rd();
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
solve();
for(i=1;i<=m;i++) {
printf("%d %d\n",ans1[i],ans[i]);
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,093
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,569
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,417
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,190
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,825
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,908