博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3236:[AHOI2013]作业(莫队,分块)
阅读量:6189 次
发布时间:2019-06-21

本文共 2217 字,大约阅读时间需要 7 分钟。

Description

Input

Output

Sample Input

3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3

Sample Output

2 2
1 1
3 2
2 1

HINT

N=100000,M=1000000

Solution

首先有一个比较显然的做法就是用莫队加树状数组……然而这样的话复杂度是$n\sqrt nlog$。

因为树状数组的修改和查询都是$log$的,所以我们用一个修改$O(1)$,查询$O(\sqrt n)$的分块代替树状数组,那么总的复杂度就是$n\sqrt n$了。

Code

1 #include
2 #include
3 #include
4 #include
5 #include
6 #define N (100009) 7 #define M (1000009) 8 #define S (359) 9 using namespace std;10 11 int n,m,a[N],l,r,x,y,ans2,Keg[N],q_num;12 int ID[N],L[S],R[S],Val[N][2],Sum[N][2];13 struct Que14 {15 int l,r,a,b,id,ans1,ans2;16 bool operator < (const Que &a) const17 {18 if (ID[l]==ID[a.l]) return r
'9') { if (c=='-') w=-1; c=getchar();}28 while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();29 return x*w;30 }31 32 void Build()33 {34 int unit=sqrt(n);35 int num=n/unit+(n%unit!=0);36 for (int i=1; i<=num; ++i)37 L[i]=(i-1)*unit+1, R[i]=i*unit;38 R[num]=n;39 for (int i=1; i<=num; ++i)40 for (int j=L[i]; j<=R[i]; ++j) ID[j]=i;41 }42 43 int Query(int l,int r,int opt)44 {45 int ans=0;46 if (ID[l]==ID[r])47 {48 for (int i=l; i<=r; ++i) ans+=Val[i][opt];49 return ans;50 }51 for (int i=l; i<=R[ID[l]]; ++i) ans+=Val[i][opt];52 for (int i=L[ID[r]]; i<=r; ++i) ans+=Val[i][opt];53 for (int i=ID[l]+1; i<=ID[r]-1; ++i) ans+=Sum[i][opt];54 return ans;55 }56 57 void Del(int p)58 {59 Val[a[p]][0]--; Sum[ID[a[p]]][0]--;60 if (!Val[a[p]][0]) Val[a[p]][1]--, Sum[ID[a[p]]][1]--;61 }62 63 void Ins(int p)64 {65 Val[a[p]][0]++; Sum[ID[a[p]]][0]++;66 if (Val[a[p]][0]==1) Val[a[p]][1]++, Sum[ID[a[p]]][1]++;67 }68 69 int main()70 {71 n=read(); m=read();72 Build();73 for (int i=1; i<=n; ++i) a[i]=read();74 for (int i=1; i<=m; ++i)75 {76 l=read(); r=read(); x=read(); y=read();77 Q[++q_num]=(Que){l,r,x,y,i};78 }79 sort(Q+1,Q+m+1);80 int l=1,r=0;81 for (int i=1; i<=m; ++i)82 {83 while (l
Q[i].l) Ins(--l);85 while (r
Q[i].r) Del(r--);87 Q[i].ans1=Query(Q[i].a,Q[i].b,0);88 Q[i].ans2=Query(Q[i].a,Q[i].b,1);89 }90 sort(Q+1,Q+m+1,cmp);91 for (int i=1; i<=m; ++i)92 printf("%d %d\n",Q[i].ans1,Q[i].ans2);93 }

转载于:https://www.cnblogs.com/refun/p/10365714.html

你可能感兴趣的文章
Java 延时常见的几种方法
查看>>
javatodo框架中怎么配置路由
查看>>
C# servicestack.redis 互通 java jedis
查看>>
MRD市场需求文档结构
查看>>
关于硬盘的一切!
查看>>
一夫老师谈如何快速学习淘宝美工?成为高级淘宝设计师学习路径分析
查看>>
Java(随笔)——利用HTML,CSS,JavaScript,JQuery编写的简易计算器
查看>>
Linux学习之Linux系统目录简概
查看>>
七十三、分发系统介绍、expect脚本远程登录、expect脚本远程执行命令、expect传递参数...
查看>>
仓库管理的5S如何在仓库中实施
查看>>
北京游戏开发学习路线:花多少钱才能成为游戏开发?
查看>>
Num43 oracle(子查询: 集合查询:处理数据:创建和管理表: 其他数据库对象)...
查看>>
站在5G潮头 爱立信如何重描金字招牌 | MWC 2019
查看>>
为了云计算的安全需要自己控制加密密钥
查看>>
从入门到精通,给Java学习者的几点建议
查看>>
论文查重
查看>>
上司:我们为什么要使用企业云盘?
查看>>
AJPFX分享java排序之希尔排序
查看>>
dwr3实现消息精确推送详细步骤
查看>>
深入学习Java虚拟机(三)
查看>>