首页 > 其他分享 >[luoguSP3267] D-query

[luoguSP3267] D-query

时间:2024-11-23 22:33:05浏览次数:4  
标签:luoguSP3267 cnt int ++ 端点 query include block

题意

给定 \(n\) 个数 \(a_1 \cdots a_n\) 和 \(q\) 个查询,每次查询区间 \([l,r]\) 中,\(a\) 的不同数的个数

sol

本题不强制在线,因此可以考虑离线算法,如莫队。
莫队是一个非常神奇的算法,它的基本思想是:将区间进行某种排序后,通过移动 \(l,r\) 指针,每次移动时处理答案的增减来得到答案。

如何排序

如果按照左右端点排序的话,左端点的移动次数为 \(O(n)\),但右端点的移动次数依然会被卡到 \(O(n^2)\),而莫队的思想是通过分块的方式,使左右端点移动次数均摊,即 \(O(n\sqrt n)\)
为此,需要按照左端点所在块为第一关键字,右端点为第二关键字进行排序。
通常来说,还会使用玄学的奇偶性优化进行卡常,即当左端点块为奇数时,右端点升序,否则右端点降序,虽然很玄学,但是会快很多,具体为什么我也不知道(

如何移动指针

当使用莫队时,往往在扩大区间时增加答案,在缩减区间时减小答案。而在某些题目中,当答案减小到负数时会出现一些莫名其妙的问题,因此在移动时我们需要先处理扩大区间,再处理缩小区间

对于本题,增减答案时只需要记录一个桶即可

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;

const int N = 30005, M = 200005, K = 1000005;

struct Ask{
    int l, r;
    int id;
} g[M];

int block[N], ans[M];
int n, q;
int a[N];
int res = 0;
int cnt[K];

bool cmp(Ask a, Ask b){
    if (block[a.l] != block[b.l]) return block[a.l] < block[b.l];
    if (block[a.l] & 1) return a.r < b.r;
    return a.r > b.r;
}

void del(int x){
    cnt[a[x]] -- ;
    if (!cnt[a[x]]) res -- ;
}

void add(int x){
    if (!cnt[a[x]]) res ++ ;
    cnt[a[x]] ++ ;
}

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);

    int sz = sqrt(n);
    int bcnt = ceil(1.0 * n / sz);

    for (int i = 1; i <= bcnt; i ++ )
        for (int j = (i - 1) * sz + 1; j <= i * sz; j ++ )
            block[j] = i;
    
    scanf("%d", &q);
    for (int i = 1; i <= q; i ++ ) scanf("%d%d", &g[i].l, &g[i].r), g[i].id = i;

    sort(g + 1, g + q + 1, cmp);

    int l = 1, r = 0;
    for (int i = 1; i <= q; i ++ ){
        int ql = g[i].l, qr = g[i].r;
        while (l > ql) add( -- l);
        while (r < qr) add( ++ r);
        while (l < ql) del(l ++ );
        while (r > qr) del(r -- );
        ans[g[i].id] = res;
    }

    for (int i = 1; i <= q; i ++ ) printf("%d\n", ans[i]);

    return 0;
}

标签:luoguSP3267,cnt,int,++,端点,query,include,block
From: https://www.cnblogs.com/XiaoJuRuoUP/p/-/luoguSP3267

相关文章

  • jQuery添加到购物车动画特效插件
    在线预览 下载 这是一款jQuery添加到购物车动画特效插件。该插件可以非常方便的制作出点击商品购买按钮,商品飞入购物车的动画特效。 使用方法在页面中引入jquery和jquery.animate_from_to-1.0.js文件。<scriptsrc="js/jquery.min.js"type="text/javascript"></script......
  • jQuery带炫酷轮播图效果的Lightbox弹出层插件
    在线预览  下载 这是一款jQuery带炫酷轮播图效果的Lightbox弹出层插件。该lightbox插件在弹出层中,可以对所有图片进行轮播。它的特点还有:简单、速度快。响应式设计。可以显示每张图片的状态。在弹出层中可以设置图片的标题和文字。支持CSS3动画。 使用方法在页......
  • jQuery固定侧边栏插件ssMenu
    在线预览  下载ssMenu是一款jQuery固定侧边栏插件。 使用方法在页面中引入ss-menu.css、jquery和ss-menu.js文件。<linkrel="stylesheet"href="css/ss-menu.css"><scriptsrc="js/jquery.min.js"type="text/javascript"></script>......
  • FDQuery的分页
    分页方法,其中PageSize为分页大小,PageIndex页码,0为第一页,RecsSkip可以通过 PageSize*PageIndex计算出来,如下: procedureTForm1.PagingQuery(Query:TFDQuery;PageSize,PageIndex:Integer);beginQuery.Disconnect;Query.FetchOptions.RecsSkip:=PageSi......
  • 前端知识整理(全屏播放器 CSS JavaScript 轮转播放 jquery库 AJAX 画布 网页测试)
    currenttime在前端开发中,“currenttime”通常指的是获取用户设备的当前时间。这可以通过JavaScript来实现,下面是一个简单的示例代码,展示如何获取并显示当前时间:<!DOCTYPEhtml><html><head><title>显示当前时间</title></head><body><h1>当前时间:</h1><pid="d......
  • 界面控件Kendo UI for jQuery 2024 Q3亮点 - 支持切换编辑模式
    随着最新的2024Q3版本,Progress使用户能够使用现成的页面模板和构建块更快地构建令人惊叹的应用程序,使您的Telerik和KendoUI开发体验更好。Telerik和KendoUI 2024Q3版本将焦点放在新推出的页面模板和构建块上,每个页面模板和构建块都预先配置了TelerikUIforBlazor、Kend......
  • abc347E Set Add Query
    有数组A[N],初始时元素都为0,另外还有初始为空的集合S。依次处理以下Q组查询:给出整数x[i],如果S包含x[i],则从S中移除x[i],否则将x[i]加入S,记此时S的大小为|S|,把|S|加到集合中的每个元素i对应的A[i]中。求最终A[i]是多少。1<=N,Q<=2E5;1<=x[i]<=N分析:记录每个时刻集合S的大小,设元素u......
  • 37_初识搜索引擎_快速掌握query string search语法以及_all metadata原理揭秘
    1、querystring基础语法GET/test_index/test_type/_search?q=test_field:testGET/test_index/test_type/_search?q=+test_field:testGET/test_index/test_type/_search?q=-test_field:test一个是掌握q=field:searchcontent的语法,还有一个是掌握+和-的含义2、_allmetada......
  • jquery中判断图片是否存在的实现代码
    有时候我们需要判断当前的图片是否存在,方便后期做一些操作,当然也可以参考上一篇文章,如果不存在就替换位默认图片functionisHasImg(src){varimg=newImage();img.src=src;img.onload=function(){if(img.width>0||img.height>0){......
  • jquery video视频轮播播放
    文章目录概要引入依赖概要通过jquery.tools.min.js实现视频缩略图轮播,点击放大播放效果图:引入依赖<scriptsrc="js/jquery-1.5.1.min.js"type="text/javascript"></script><scriptsrc="js/jquery.tools.min.js"type="text/javascript">......