首页 > 其他分享 >树套树板子,但是带修莫队+值域分块

树套树板子,但是带修莫队+值域分块

时间:2023-11-09 21:22:26浏览次数:31  
标签:return 树套 分块 int re && -- define 修莫队

\(\text{Link - Luogu Blog}\)

原题传送门

没啥重要的事情,就是终于过了这题非常开心,发现自己是莫队的时间戳部分写错了调了 114514 年我也只能说是十分趣味。

以及今天深刻地认识到了带修莫队应该 len=pow(n,0.66);

就是裸的带修莫队+值域分块,就不说了,直接放代码了昂。

如果有人写这个做法的话或许这可以带来一点帮助?

加了光读,用的普通 cout,总用时 945ms,每个测试点用时不超过 150ms!说实话跑得真的很快啊!重铸根号荣光! 我不是根号批。

\(\text{record}\)


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define re register
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
const int N=5e4+113,V=1e5+113,sq=360,Zi_Gao=2147483647;
int n,m,a[N],cnt_que,cnt_upd,ans[N],idx;
int id[V],bl[sq],br[sq],len,vmax,b[V],sum[sq],cnt[V];
il int read(){
    re int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}
struct query{
    int op,l,r,x,t,id;
}q[N];
il bool cmp(query x,query y){
    if(id[x.l]^id[y.l])return x.l<y.l;
    if(id[x.r]^id[y.r])return x.r<y.r;
    return x.t<y.t;
}
struct update{
    int place,x;
}u[N];
il void init(){
    for(re int i=1;i<=cnt_upd;i++)b[++idx]=u[i].x;
    for(re int i=1;i<=cnt_que;i++)
        if(q[i].op!=2)b[++idx]=q[i].x;
    vmax=idx;
    sort(b+1,b+1+vmax);
    vmax=unique(b+1,b+1+vmax)-b-1;
    len=sqrt(vmax);
    for(re int i=1;i<=vmax;i++)id[i]=(i-1)/len+1;
    for(re int i=1;i<=id[vmax];i++)
        bl[i]=br[i-1]+1,br[i]=i*len;
    br[id[vmax]]=vmax;
    for(re int i=1;i<=n;i++)
        a[i]=lower_bound(b+1,b+1+vmax,a[i])-b;
    for(re int i=1;i<=cnt_upd;i++)
        u[i].x=lower_bound(b+1,b+1+vmax,u[i].x)-b;
    for(re int i=1;i<=cnt_que;i++)
        if(q[i].op!=2)q[i].x=lower_bound(b+1,b+1+vmax,q[i].x)-b;
}
#define Add(x) cnt[x]++,sum[id[x]]++
#define Del(x) cnt[x]--,sum[id[x]]--
il int solve_1(int x){
    int res=0;
    for(re int i=1;i<id[x];i++)res+=sum[i];
    for(re int i=bl[id[x]];i<x;i++)res+=cnt[i];
    return res+1;
}
il int solve_2(int x){
    int tot=0;
    for(re int i=1;i<=id[vmax];i++){
        tot+=sum[i];
        if(tot>=x){
            tot-=sum[i];
            for(re int j=bl[i];j<=br[i];j++){
                tot+=cnt[j];
                if(tot>=x)return b[j];
            }
        }
    }
    return Zi_Gao;
}
il int solve_4(int x){
    for(re int i=x-1;i>=bl[id[x]];i--)
        if(cnt[i])return b[i];
    for(re int i=id[x]-1;i;i--)
        if(sum[i])
            for(re int j=br[i];j>=bl[i];j--)
                if(cnt[j])return b[j];
    return -Zi_Gao;
}
il int solve_5(int x){
    for(re int i=x+1;i<=br[id[x]];i++)
        if(cnt[i])return b[i];
    for(re int i=id[x]+1;i<=id[vmax];i++)
        if(sum[i])
            for(re int j=bl[i];j<=br[i];j++)
                if(cnt[j])return b[j];
    return Zi_Gao;
}
int main(){
    n=read(),m=read();
    len=pow(n,0.66);
    for(re int i=1;i<=n;i++)
        a[i]=read(),id[i]=(i-1)/len+1,b[++idx]=a[i];
    for(re int i=1;i<=m;i++){
        int op=read();
        if(op==3){
            cnt_upd++;
            u[cnt_upd].place=read(),u[cnt_upd].x=read();
            continue;
        }
        cnt_que++;
        q[cnt_que].op=op,q[cnt_que].l=read(),q[cnt_que].r=read(),q[cnt_que].x=read();
        q[cnt_que].t=cnt_upd,q[cnt_que].id=cnt_que;
    }
    sort(q+1,q+1+cnt_que,cmp);
    init();
    re int L=1,R=0,T=0;
    for(re int i=1;i<=cnt_que;i++){
        re int l=q[i].l,r=q[i].r,x=q[i].x,op=q[i].op;
        while(R<r)R++,Add(a[R]);
        while(L>l)L--,Add(a[L]);
        while(R>r)Del(a[R]),R--;
        while(L<l)Del(a[L]),L++;
        while(T<q[i].t){
            T++;
            int pla=u[T].place;
            if(pla>=l&&pla<=r)Del(a[pla]),Add(u[T].x);
            swap(u[T].x,a[pla]);
        }
        while(T>q[i].t){
            int pla=u[T].place;
            if(pla>=l&&pla<=r)Del(a[pla]),Add(u[T].x);
            swap(u[T].x,a[pla]);
            T--;
        }
        if(op==1)ans[q[i].id]=solve_1(x);
        if(op==2)ans[q[i].id]=solve_2(x);
        if(op==4)ans[q[i].id]=solve_4(x);
        if(op==5)ans[q[i].id]=solve_5(x);
    }
    for(re int i=1;i<=cnt_que;i++)cout<<ans[i]<<'\n';
    return 0;
}

标签:return,树套,分块,int,re,&&,--,define,修莫队
From: https://www.cnblogs.com/MrcFrst-LRY/p/17822879.html

相关文章

  • 分块:优雅的暴力
    之前我并没有感觉到分块的暴力属性今天卡常的时候莫名其妙的感觉到了我甚至觉得自己经历了分块的诞生历程今天本来在对一个分块题卡常但是我直接写的纯暴力,一直差一点卡过于是我想到了各种优化:加\(inline\)(别说还真有用),加\(register\)(感觉这个没用)...\(bitset\)记......
  • command_block的 《分块相关杂谈》注
    目录0x00分块概论0x10基础数列分块原文链接0x00分块概论大概可以理解为将一段数组分成长度大约为\(\sqrt{n}\)长度的块,对于一段区间\(\left[l,r\right]\),我们可以将其拆分为三大部分:\(\left[l,bl\timeslen+len-1\right]\)的暴力区间,\(\left[bl\timeslen+len,br\time......
  • 数论分块
    一、应用情景求\(\sum\limits_{i=1}^{n}g(i)\lfloor\fracni\rfloor,n\leq10^{12}\)二、常见结合莫比乌斯反演……三、算法原理&代码实现实际上,\(~\lfloor\fracni\rfloor~\)的取值其实最多只有\(~2\times\sqrtn~\)种:对于\(~i\in[1,\sqrtn]~\):只有\(~\sqrt......
  • springboot 整合 gridfs 、webUploader实现大文件分块上传、断点续传、秒传
    主要的pom.xml:<dependency>      <groupId>mysql</groupId>      <artifactId>mysql-connector-java</artifactId>    </dependency><!--mongodb-->    <dependency>      <groupId>org.spri......
  • Nityacke的Top Cluster树分块
    我们有对序列分块的需求。所以我们有对树分块的需求。有些出题人喜欢把序列问题放到树上,从而让选手强行写树链剖分。但是我们想让大家知道,搬到仙人掌上也是可以的。先给出一些信息:一个树簇(cluster)是树上的一个连通子图,有至多两个点和全树的其他位置连接。这两个节点......
  • 算法笔记(6)数列分块
    原发表于我的博客前言分块不能说是一种数据结构,它是一种思想,无论是数列分块,块状链表,还是数论分块,莫队算法,都应用了分块的思想。本文主要介绍狭义上的分块,即数列分块。数列分块的引入数列分块可以说是暴力,一种优美的暴力,它的基本思路是,把数列分成若干块(一般取\(\sqrtn\)),分块......
  • HTTP——断点续传(分块传输)
    HTTP——断点续传(分块传输)断点续传:指的是在上传/下载时,将任务(一个文件或压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传/下载,如果碰到网络故障,可以从已经上传/下载的部分开始继续上传/下载未完成的部分,而没有必要从头开始上传/下载。可以节省时间,提高速度。断点续传......
  • 【ZROJ2730】简单题 可持久化分块题解
    Description给定一棵\(n\)个节点的树,每次询问编号为\([l,r]\)的点中有多少个是祖先关系。\(n,q\le10^5\)。Solution直接做的话树上的祖先关系不好统计,那么转化到\(\texttt{dfs}\)序上,如果\(u\)是\(v\)的祖先那么\(dfn_u\ledfn_v<dfn_u+siz_u\)。把\([d......
  • 数论分块
    数论分块在P2424偶然学到了这个算法,觉得很有意思,于是单拎出来再学习一下。数论分块,又叫整数分块,解决$f(n)=\sum_{i=1}^{n}g(i)\times\lfloor\frac{n}{i}\rfloor$一类问题。观察发现是成段出现,比如说时数列是这样的:设区间的右端点为,$r=\frac{n}{\lfloor\frac......
  • 14.3 Socket 字符串分块传输
    首先为什么要实行分块传输字符串,一般而言Socket套接字最长发送的字节数为8192字节,如果发送的字节超出了此范围则后续部分会被自动截断,此时将字符串进行分块传输将显得格外重要,分块传输的关键在于封装实现一个字符串切割函数,将特定缓冲区内的字串动态切割成一个个小的子块,当切割结......