zoukankan      html  css  js  c++  java
  • 【洛谷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;
    }
    
  • 相关阅读:
    Swing-文本输入组件(一)
    JFrame常用属性设置模板
    Swing-BoxLayout用法-入门
    linux创建和查看用户命令
    elasticsearch,http://ip:9200访问不到的解决办法
    U盘制作Linux系统盘
    Linux中oracle的安装,亲测
    Linux中yum的安装
    Linux中oracle安装时候报ora-00119解决办法
    eclipse中多个工程编译到同一个目录下
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998146.html
Copyright © 2011-2022 走看看