zoukankan      html  css  js  c++  java
  • 莫队总结

    莫队总结

    离线莫队

    for(int i=1;i<=m;++i){
        int ql=q[i].l,qr=q[i].r;
        while(l<ql) del(l++);
        while(l>ql) add(--l);
        while(r<qr) add(++r);
        while(r>qr) del(r--);
        qans[q[i].qid]=ans;
    }
    

    离线处理询问,暴力按一定顺序处理区间询问,这样我们可以利用上一次询问得到的信息来处理当前询问,大大加快速度。

    我们一般先按每块(sqrt{n})大小对各询问区间左端点分块编号(其中(n)为总区间大小,(m)为询问次数,注意随机数据时(frac{n}{sqrt{m imesfrac{2}{3}}})更优),同一块内的按右端点排序,否则按左端点,按排序后的顺序处理询问,总复杂度为(O(n imessqrt{n}))

    这里还有一种卡常排序方法比上述排序方式更优:

    inline bool cmp(nod a, nod b){
    	return ((a.bid^b.bid)?(a.l<b.l):((a.bid&1)?a.r<b.r:a.r>b.r));
    }
    

    具体原理:

    这样能快是因为指针移到右边后不用再跳回左边,而跳回左边后处理下一个块又要跳回右边,这样能减少一半操作,理论上能快一倍

    ——莫队算法初探

    各询问区间转移必须(O(1)),否则会T爆,所以只要能想出(O(1))的方式转移([l,r]),莫队就不难了。

    另外莫队小心初始化,直接l=0,r=0等可能会炸。

    板子(SP326 DQUERY - D-query):

    // luogu-judger-enable-o2
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int n,block,a[500005];
    int cnt[1000010],ans,l,r;
    inline void add(int x){
    	ans+=(++cnt[a[x]]==1);
    }
    inline void del(int x){
    	ans-=(--cnt[a[x]]==0);
    }
    struct nod{
    	int l,r,qid,bid;
    } q[500005];
    inline bool cmp(nod a, nod b){
    	return ((a.bid^b.bid)?a.l<b.l:((a.bid&1)?a.r<b.r:a.r>b.r));
    }
    int qans[500005];
    inline int read(){
        char ch;int s=0;
        ch = getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
        return s;
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i) a[i]=read();
    	int m=read();
    	block=n/sqrt(m*2/3);
    	for(int i=1;i<=m;++i){
    		q[i].l=read(),q[i].r=read();
    		q[i].qid=i;
    		q[i].bid=q[i].l/block;
    	}
    	sort(q+1, q+1+m, cmp);
    	l=1,r=0;
    	for(int i=1;i<=m;++i){
    		int ql=q[i].l,qr=q[i].r;
    		while(l<ql) del(l++);
    		while(l>ql) add(--l);
    		while(r<qr) add(++r);
    		while(r>qr) del(r--);
    		qans[q[i].qid]=ans;
    	}
    	for(int i=1;i<=m;++i) printf("%d
    ", qans[i]);
    	return 0;
    }
    

  • 相关阅读:
    css
    css加号波浪号
    C++对象池
    C++11 智能指针
    C++内存泄漏检测(调试工具)
    JSONP是个嘛玩意?解决跨域问题?
    使用django + KindEditor 开发个人博客系统
    前端文本框插件KindEditor
    jQuery AJAX
    Django ModelForm表单验证
  • 原文地址:https://www.cnblogs.com/santiego/p/11250388.html
Copyright © 2011-2022 走看看