【洛谷P1972】【BZOJ1878】HH的项链【莫队】

题目大意:

题目链接:
洛谷:https://www.luogu.org/problemnew/show/P1972
BZOJ:https://www.lydsy.com/JudgeOnline/problem.php?id=1878

给出一个序列,询问[li,ri][l_i,r_i]中有多少个不同数字。


思路:

莫队裸题。其实就是 这道题 的弱化版(不用修改)
但是这道题卡莫对。开Ofast,O3Ofast,O3会MLE。
莫队方法就不讲了,相信大家都会。这里就讲一下如何用莫队卡过这道题。

  1. 输入输出优化
  2. 块长T=1250T=1250
  3. 合并语句。
    这样可以大大提高程序的效率。除了码风奇丑意外都还好

到此为止程序可以卡进1200ms1200ms。最初始的莫队是2000+ms2000+ms的。
实在不知道怎么剪了。于是看了一下卡过的莫队代码。
发现他们的排序都没有用cmpcmp,而是搞了个这个

bool operator < (const Ask &a,const Ask &b){
	return pos[a.l]^pos[b.l] ? a.l<b.l : pos[a.l]&1 ? a.r<b.r:a.r>b.r;
}

从条件语句中看,这个显然是代替cmpcmp的。
而且可以大大加快速度。具体原因我也不知道qwqqwq

  1. 加上这个玄学优化。
  2. 开洛谷自带O2O2

这样就可以很稳的过掉这道题了。
在这里插入图片描述

可以看到最慢点600ms600ms内,已经算是很快的了。


代码:

// luogu-judger-enable-o2
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <algorithm>
#define reg register
using namespace std;

const int N=500010,M=1000010;
int n,m,l,r,sum,T,a[N],cnt[M],pos[N],ans[N];

struct Ask
{
    int l,r,id;
}ask[N];

bool operator < (const Ask &a,const Ask &b)
{
    return pos[a.l]^pos[b.l] ? a.l<b.l : pos[a.l]&1 ? a.r<b.r:a.r>b.r;
}

inline int read()
{
    int d=0;
    char ch=getchar();
    while (!isdigit(ch)) ch=getchar();
    while (isdigit(ch))
        d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    return d;
}

inline void write(int x)
{
    if (x>9) write(x/10);
    putchar(x%10+48);
}

int main()
{
    n=read();
    T=1250;
    for (reg int i=1;i<=n;++i)
    {
        a[i]=read();
        pos[i]=(i-1)/T+1;
    }
    m=read();
    for (reg int i=1;i<=m;++i)
    {
        ask[i].l=read(); ask[i].r=read();
        ask[i].id=i;
    }
    sort(ask+1,ask+1+m);
    l=1;
    for (reg int i=1;i<=m;++i)
    {
        while(l>ask[i].l) sum+=(++cnt[a[--l]]==1);
        while(l<ask[i].l) sum-=(--cnt[a[l++]]==0);
        while(r>ask[i].r) sum-=(--cnt[a[r--]]==0);
        while(r<ask[i].r) sum+=(++cnt[a[++r]]==1);
        ans[ask[i].id]=sum;
    }
    for (reg int i=1;i<=m;++i)
        write(ans[i]),putchar(10);
    return 0;
}
posted @ 2019-06-06 14:26  全OI最菜  阅读(110)  评论(0编辑  收藏  举报