大题思路就是分块,将n个数分成sqrt(n)个块,然后

处理出一个w数组,w[i,j]代表第i个块到第j个块的答案

那么对于每组询问l,r如果l,r在同一个块中,直接暴力做就行了

如果不在同一个块中,l,r区间中整块的部分可以直接由w数组得到答案

然后多出来的部分暴力处理下出现次数,然后再预处理一个b数组,代表没

个数出现的位置,且每个数都连续,那么我们可以二分的找出在多余部分出现的

每个数在整区间内出现多少次,然后和多余部分出现的累加,判断奇偶更新答案

看了lyd的题解,写的挺好(其实这个题就是他出的。。),然后我写的

pascal,他的C++的代码30s+A了,我就TLE了。。。

话说今儿LYD生日,然后SHY发了个说说祝他生日快乐,是我想多了。。。

/**************************************************************
    Problem:
    User: BLADEVIL
    Language: Pascal
    Result: Time_Limit_Exceed
****************************************************************/
 //By BLADEVIL
{$inline on}
var
    n, t, m                     :longint;
    a, b, c                     :array[..] of longint;
    st, ed, s, e, v, q          :array[..] of longint;
    w                           :array[..,..] of longint;
 
procedure swap(var a,b:longint);inline;
var
    c                           :longint;
begin
    c:=a; a:=b; b:=c;
end;
     
function calc(k,x,y:longint):longint;inline;
var
    l, r, mid                   :longint;
begin
    if x>y then exit();
    l:=st[k]; r:=ed[k];
    while l<r do
    begin
        mid:=(l+r+)>>;
        if b[mid]<x then l:=mid else r:=mid-;
    end;
    if b[l]>=x then dec(l);
    x:=l;
    l:=st[k]; r:=ed[k];
    while l<r do
    begin
        mid:=(l+r+)>>;
        if b[mid]>y then r:=mid- else l:=mid;//
    end;
    if b[l]>y then dec(l);
    y:=l;
    exit(y-x);
end;
     
procedure main;inline;
var
    i, j, k                     :longint;
    p, tot, l, r                :longint;
    now, cnt                    :longint;
    x, y                        :longint;
     
begin  
    read(n,t,m);
    for i:= to n do read(a[i]);
    for i:= to n do inc(c[a[i]]);
    tot:=;
    for i:= to t do
    begin
        st[i]:=tot+;
        inc(tot,c[i]);
        ed[i]:=tot;
    end;
    fillchar(c,sizeof(c),);
    for i:= to n do
    begin
        b[st[a[i]]+c[a[i]]]:=i;
        inc(c[a[i]]);
    end;
    p:=trunc(sqrt(n));
    l:=n div p;
    for i:= to p do
    begin
        s[i]:=(i-)*l+;
        e[i]:=i*l;
    end;
    if e[p]<n then
    begin
        inc(p);
        s[p]:=e[p-]+;
        e[p]:=n;
    end;
    for i:= to p do
    begin
        fillchar(c,sizeof(c),);
        now:=;
        for j:=i to p do
        begin
            for k:=s[j] to e[j] do
            begin
                inc(c[a[k]]);
                if (c[a[k]]>) and (c[a[k]] and <>)
                    then dec(now) else
                if (c[a[k]] and )= then inc(now);
            end;
            w[i,j]:=now;
        end;
    end;
    now:=;
    for i:= to m do
    begin
        read(x,y);
        x:=(x+now) mod n+;
        y:=(y+now) mod n+;
        if x>y then swap(x,y);
        for j:= to p do
            if x<=e[j] then
            begin
                l:=j;
                break;
            end;
        for j:=p downto do
            if y>=s[j] then
            begin
                r:=j;
                break;
            end;
        now:=w[l+,r-];
        if l=r then
        begin
            for j:=x to y do
                if v[a[j]]<>i then
                begin
                    v[a[j]]:=i;
                    c[a[j]]:=;
                end else
                begin
                    inc(c[a[j]]);
                    if (c[a[j]] and )<> then
                        dec(now) else inc(now);
                end;
        end else
        begin
            cnt:=;
            for j:=x to e[l] do
                if v[a[j]]<>i then
                begin
                    v[a[j]]:=i;
                    c[a[j]]:=;
                    inc(cnt);
                    q[cnt]:=a[j];
                end else inc(c[a[j]]);
            for j:=s[r] to y do
                if v[a[j]]<>i then
                begin
                    v[a[j]]:=i;
                    c[a[j]]:=;
                    inc(cnt);
                    q[cnt]:=a[j];
                end else inc(c[a[j]]);
            for j:= to cnt  do
            begin
                k:=calc(q[j],s[l+],e[r-]);
                if k= then
                begin
                    if c[q[j]] and = then inc(now)
                end else
                if (k and <>) and (c[q[j]] and <>) then inc(now) else
                if (k and =) and (c[q[j]] and <>) then dec(now);
            end;
        end;
        writeln(now);
    end;
     
end;
 
 
begin
    main;
end.

bzoj 2821 分块处理的更多相关文章

  1. bzoj 2821 分块

    分块: 先预处理,将原序列分成长度为len的许多块,计算从第i块到第j块的答案,(可以做到O(n*n/len)). 每次询问时,将询问的区间分成三部分,:左边,中间,右边,中间是尽量大的一个块区间,其 ...

  2. BZOJ 2821 分块+二分

    题意: N个数,M组询问,每次问[l,r]中有多少个数出现正偶数次. 思路: 把N个数分成sqrt(n)块,预处理d[i][j]表示第i块起点到第j块末尾的答案 枚举起点i,并维护一个数组记录每个数到 ...

  3. [BZOJ 2821] 作诗(Poetize) 【分块】

    题目链接:BZOJ - 2821 题目分析 因为强制在线了,所以无法用莫队..可以使用分块来做. 做法是,将 n 个数分成 n/x 个块,每个块大小为 x .先预处理出 f[i][j] ,表示从第 i ...

  4. [BZOJ 2821] 作诗

    Link: BZOJ 2821 传送门 Solution: 一道类似区间众数的经典分块 由于个数为偶数这样的条件不能支持快速合并 因此要先$O(n*sqrt(n))$预处理出$pre[i][j]$表示 ...

  5. BZOJ 2821: 作诗(Poetize)( 分块 )

    分块,分成N^0.5块.O(N^1.5)预处理出sm[i][j]表示前i块中j的出现次数, ans[i][j]表示第i~j块的答案. 然后就可以O(N^0.5)回答询问了.总复杂度O((N+Q)N^0 ...

  6. BZOJ 2821作诗(Poetize) 分块

    Description 有一个长度为n的序列,序列每个元素的范围[1,c],有m个询问x y,表示区间[x,y]中出现正偶数次的数的种类数. Solution 大力分块解决问题. 把序列分块,f[i] ...

  7. bzoj 2821 作诗 分块

    基本思路和蒲公英一样 还是预处理出每两个块间的答案 询问时暴力跑两边的贡献 #include<cstdio> #include<cstring> #include<ios ...

  8. 【BZOJ 2821】作诗

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2821 [算法] 如果不强制在线,显然莫队是可以解决此题的,那么,强制在线怎么办呢? ...

  9. bzoj 2741 分块+可持久化trie

    多个询问l,r,求所有子区间异或和中最大是多少 强制在线 做法: 分块+可持久化trie 1.对于每块的左端点i,预处理出i到任意一个j,()i,j)间所有子区间异或和中最大为多少,复杂度O(\(n\ ...

随机推荐

  1. 【积硅计划】http协议基础

    http:超文本传输协议,它允许将超文本标记(html)文档从web服务器传送到浏览器.目前版本HTTP/1.1   http请求过程:   proxy:代理服务器,网络信息的中转站.功能如下:   ...

  2. 4)Java容器类相关知识

    1>Array 和 Arrays:   Arrays:用来操作array的工具类,其中包含一组static函数:      equals():比较两个array 是否相等. array拥有相同元 ...

  3. adb 修改system文件

    1. $ adb push SecureSetting.apk /sdcard/  // 上传要安装的文件,为安装做准备.     2. $ adb shell     3. $ su // 切换到  ...

  4. Laravel 5 基础(十二)- 认证

    Laravel 出厂已经带有了用户认证系统,我们来看一下 routes.php,如果删除了,添加上: Route::controllers([ 'auth' => 'Auth\AuthContr ...

  5. PHP JS HTML ASP页面跳转代码 延时跳转代码 返回到上一界面并刷新 JS弹出指定大小的新窗口

    1.PHP延时跳转代码 //跳转到浏览界面 header("Refresh:1;url=machine_list.php"); //不延时 <?php header(&quo ...

  6. SQL Server 基础:Join用法

    Join(麻蛋  废话不多说 有图有真相) 测试数据脚本 CREATE TABLE Atable ( S# INT, Sname ), Sage INT, Sfrom ) ) insert into ...

  7. python解析页面上json字段

    一般来说,当我们从一个网页上拿下来数据,就是一个字符串,比如: url_data = urllib2.urlopen(url).readline() 当我们这样得到页面数据,url_data是全部页面 ...

  8. FLEX AS3.0 百度地图

    window xp系统 FlashBuilder4.5 先上百度下载flash api 下载地址http://developer.baidu.com/map/flash.htm 新建一个flex项目 ...

  9. CodeForces 569A 第八次比赛 C题

    Description Little Lesha loves listening to music via his smartphone. But the smartphone doesn't hav ...

  10. EMVTag系列6《IAC 发卡行行为代码》

    R(需求):数据应存在,在读应用数据过程中,终端不检查:将变成必备 L: 5 IAC 的值,最好不要自定义,最好和所选的模板完全匹配.如果修改持卡人认证位,PIN Bypass 相关的位.如果有业务需 ...