收获:

  1、分块时顺便记录每个位置所属的块,然后一次排序就OK了。

  2、要权衡在“区间移动”与“查询结果”之间的时间,莫队算法一般区间移动频率远大于查询结果,所以我们选择的辅助数据结构时就要注意了,我最开始写的是值域线段树,自己生成的极限数据要1m8s,改成树状数组后要24s,还是过不了,hzwer只要13s,细看hzwer的代码,发现Ta用的是分块,O(1)修改O(n0.5)查询,改成分块后的确快多了。

  3、块的大小理论最优值是O(n*m-0.5),最开始设成这个交上去35卡过,改成hzwer的n/2后29s,所以做题时要自己试一下。

 /**************************************************************
Problem: 3809
User: idy002
Language: C++
Result: Accepted
Time:29336 ms
Memory:26988 kb
****************************************************************/ #include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 100010
#define maxm 1000010
#define lowbit(i) ((i)&(-(i)))
using namespace std; int n, m;
int lx[maxn], rx[maxn], mccno[maxn], stot;
int w[maxn];
int ans[maxm];
int cnt[maxn], siz[maxn], cmc[maxn]; struct Qu {
int l, r, a, b, id;
bool operator<( const Qu & c ) const {
return mccno[l]<mccno[c.l] || ( mccno[l]==mccno[c.l] && r<c.r );
}
};
Qu qu[maxm]; void add( int pos ) {
siz[pos]++;
if( siz[pos]== ) cmc[mccno[pos]]++;
}
void del( int pos ) {
siz[pos]--;
if( siz[pos]== ) cmc[mccno[pos]]--;
}
int query( int l, int r ) {
int lm = mccno[l], rm = mccno[r];
int rt = ;
if( lm==rm ) {
for( int j=l; j<=r; j++ )
if( siz[j] ) rt++;
return rt;
}
for( int b=lm+; b<rm; b++ )
rt += cmc[b];
for( int j=l; j<=rx[lm]; j++ )
if( siz[j] ) rt++;
for( int j=lx[rm]; j<=r; j++ )
if( siz[j] ) rt++;
return rt;
}
void partition() {
int len = (int)ceil(sqrt(n/)+);
stot = n/len;
rx[] = ;
for( int i=; i<=stot; i++ ) {
lx[i] = rx[i-]+;
rx[i] = rx[i-]+len;
}
if( rx[stot]!=n ) {
stot++;
lx[stot] = rx[stot-]+;
rx[stot] = n;
}
for( int i=; i<=stot; i++ )
for( int j=lx[i]; j<=rx[i]; j++ )
mccno[j] = i;
}
void work() {
sort( qu+, qu++m); int lf = qu[].l;
int rg = qu[].r;
for( int j=lf; j<=rg; j++ )
add(w[j]);
ans[qu[].id] = query( qu[].a, qu[].b );
for( int q=; q<=m; q++ ) {
while( qu[q].l<lf ) add(w[--lf]);
while( qu[q].l>lf ) del(w[lf++]);
while( qu[q].r>rg ) add(w[++rg]);
while( qu[q].r<rg ) del(w[rg--]);
ans[qu[q].id] = query( qu[q].a, qu[q].b );
}
}
int main() {
scanf( "%d%d", &n, &m );
for( int i=; i<=n; i++ )
scanf( "%d", w+i );
for( int i=; i<=m; i++ ) {
scanf( "%d%d%d%d", &qu[i].l, &qu[i].r, &qu[i].a, &qu[i].b );
qu[i].id = i;
}
partition();
work();
for( int i=; i<=m; i++ )
printf( "%d\n", ans[i] );
}

bzoj 3809 莫队的更多相关文章

  1. BZOJ 3809 莫队+(分块|BIT)

    #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> ...

  2. BZOJ 3339 & 莫队+"所谓的暴力"

    题意: 给一段数字序列,求一段区间内未出现的最小自然数. SOL: 框架显然用莫队.因为它兹瓷离线. 然而在统计上我打了线段树...用&维护的结点...400w的线段树...然后二分查找... ...

  3. bzoj 2038 莫队算法

    莫队算法,具体的可以看10年莫涛的论文. 大题思路就是假设对于区间l,r我们有了一个答案,那么对于区间l,r+1,我们 可以暴力的转移一个答案,那么对于区间l1,r1和区间l2,r2,需要暴力处理 的 ...

  4. bzoj 3289 莫队 逆序对

    莫队维护逆序对,区间左右增减要分类讨论. 记得离散化. /************************************************************** Problem: ...

  5. bzoj 2038 莫队入门

    http://www.lydsy.com/JudgeOnline/problem.php?id=2038 题意:多次询问区间内取出两个相同颜色的种类数 思路:由于不是在线更新,那么可以进行离线查询,而 ...

  6. bzoj 3339 莫队

    题意: 求任意一个区间的SG函数. 想到线段树,但是线段树合并很麻烦. 线段树——分块. 分块的一个应用就是莫队算法. 怎么暴力递推呢? 从一个区间到另一个区间,Ans 取决于 Ans 和 加入和删除 ...

  7. BZOJ 3236 莫队+树状数组

    思路: 莫队+树状数组 (据说此题卡常数) yzy写了一天(偷笑) 复杂度有点儿爆炸 O(msqrt(n)logn) //By SiriusRen #include <cmath> #in ...

  8. BZOJ 3339 && BZOJ 3585 莫队+权值分块

    显然若一个数大于n就不可能是答案. #include <iostream> #include <cstring> #include <cstdio> #includ ...

  9. BZOJ 2308 莫队入门经典

    题目链接  https://www.lydsy.com/JudgeOnline/problem.php?id=2038 参考博客 https://www.cnblogs.com/Paul-Guderi ...

随机推荐

  1. LOW逼三人组(二)----选择排序算法

    选择排序思路: 算法程序: def cal_time(func): # 装饰器 ,用来检测算法所执行的时间 def wrapper(*args,**kwargs): t1=time.time() re ...

  2. Feather包实现数据框快速读写,你值得拥有

    什么是Feather? Feature是一种文件格式,支持R语言和Python的交互式存储,速度更快.目前支持R语言的data.frame和Python pandas 的DataFrame. Feat ...

  3. 【nginx+tomcat集群】Nginx1.12.2+Tomcat7集群+负载均衡+Session共享

    今天想着将项目优化一下,就想的实现集群分布,在本机测试:利用nginx+tomcat实现 通过上一篇博客(http://www.cnblogs.com/qlqwjy/p/8535235.html),N ...

  4. 某团队线下赛AWD writeup&Beescms_V4.0代码审计

    还是跟上篇一样.拿别人比赛的来玩一下.  0x01 预留后门 连接方式: 0x02 后台登录口SQL注入 admin/login.php 在func.php当中找到定义的check_login函数 很 ...

  5. python常用运维脚本实例【转】

    file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函数open()来打开一个文件 . 首先 ...

  6. RAID总结

    RAID-0: 这种模式若使用相同型号容量的磁盘来组成效果最佳.这种模式RAID会先将磁盘切出等量的区块chunk,当文件要存入RAID时先按照chunk的大小切割好,再依次存放到各个磁盘中去,由于磁 ...

  7. 【并行计算】用MPI进行分布式内存编程(二)

    通过上一篇中,知道了基本的MPI编写并行程序,最后的例子中,让使用0号进程做全局的求和的所有工作,而其他的进程却都不工作,这种方式也许是某种特定情况下的方案,但明显不是最好的方案.举个例子,如果我们让 ...

  8. 在Ubuntu上安装搜狗输入法

    1.进入搜狗输入法官网 2.下载Linux版本,选择64bit 下载 3.等待下载的同时,进行系统配置 进入系统设置->语言支持->进行更新(需要输入登录密码)->在键盘输入法系统选 ...

  9. AWS 使用总结

    A.升配置的流程: 1.新开一台配置较高的机器; 2.将新机器和老机器的磁盘都取消关联,注意需要记录下老机器的磁盘分区设备名,如:/dev/sda1: 3.将老机器的磁盘挂载到新机器上,磁盘分区设备名 ...

  10. PHP解决并发问题的几种实现

    对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了 在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制. 方案一:使用文件锁排它锁 f ...