首页 > 其他分享 >[LNOI2014] LCA

[LNOI2014] LCA

时间:2024-10-22 21:10:49浏览次数:1  
标签:getch return ++ LNOI2014 int str LCA buf

[LNOI2014] LCA

乐子

image

笑点解析:单log疯狂卡常才卡过那两双log做法。

全局平衡二叉树解法。

考虑差分,然后挂扫描线。\(dep_{LCA(x,y)}\)实际上就是将\(x\)到根的节点权值加1,然后求\(y\)到根的节点的权值和。

然后就是全局平衡二叉树的板子,标记永久化写就好了。

应该会抽时间写一个全局平衡二叉树的学习笔记,会把这道题当做例题,所以这里就不多说了。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define rep(i,s,t,p) for(register int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(register int i = s;i >= t; i -= p)
namespace IO{
    #ifdef LOCAL
    FILE*Fin(fopen("in.in","r")),*Fout(fopen("out.out","w"));
    #else
    FILE*Fin(stdin),*Fout(stdout);
    #endif
    class qistream{static const size_t SIZE=1<<27,BLOCK=64;FILE*fp;char buf[SIZE];int p;public:qistream(FILE*_fp=stdin):fp(_fp),p(0){fread_unlocked(buf+p,1,SIZE-p,fp);}void flush(){memmove(buf,buf+p,SIZE-p),fread_unlocked(buf+SIZE-p,1,p,fp),p=0;}qistream&operator>>(char&str){str=getch();while(isspace(str))str=getch();return*this;}template<class T>qistream&operator>>(T&x){x=0;p+BLOCK>=SIZE?flush():void();bool flag=false;for(;!isdigit(buf[p]);++p)flag=buf[p]=='-';for(;isdigit(buf[p]);++p)x=x*10+buf[p]-'0';x=flag?-x:x;return*this;}char getch(){return buf[p++];}qistream&operator>>(char*str){char ch=getch();while(ch<=' ')ch=getch();for(int i=0;ch>' ';++i,ch=getch())str[i]=ch;return*this;}}qcin(Fin);
    class qostream{static const size_t SIZE=1<<27,BLOCK=64;FILE*fp;char buf[SIZE];int p;public:qostream(FILE*_fp=stdout):fp(_fp),p(0){}~qostream(){fwrite_unlocked(buf,1,p,fp);}void flush(){fwrite_unlocked(buf,1,p,fp),p=0;}template<class T>qostream&operator<<(T x){int len=0;p+BLOCK>=SIZE?flush():void();x<0?(x=-x,buf[p++]='-'):0;do buf[p+len]=x%10+'0',x/=10,++len;while(x);for(int i=0,j=len-1;i<j;++i,--j)swap(buf[p+i],buf[p+j]);p+=len;return*this;}qostream&operator<<(char x){putch(x);return*this;}void putch(char ch){p+BLOCK>=SIZE?flush():void();buf[p++]=ch;}qostream&operator<<(char*str){for(int i=0;str[i];++i)putch(str[i]);return*this;}}qcout(Fout);
}using namespace IO;
#define rint register int
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#define vec vector
#define eb emplace_back
#define N 50001
#define mod 201314
__int128_t base = 1;
template<class T>
inline T Mod(T x){return x-mod*(base*x>>64);}
vec<int> e[N];
int n,m,cq;
int siz[N],son[N],fa[N],c[N],sc[N],ss[N],lc[N],rc[N],ans[N];
int tag[N],sum[N];
struct node{int id,x,z;bool sgn;}q[N<<1];
void dfs1(rint x){
    siz[x] = 1;
    for(int y:e[x]){
        if(y == fa[x]) continue;
        fa[y] = x;dfs1(y);siz[x] += siz[y];
        if(!son[x] || siz[son[x]] < siz[y]) son[x] = y;
    }
}
int buildc(rint ql,rint qr){
    rint l = ql,r = qr,pos = 0,len = (sc[qr] - sc[ql]);
    while(l <= r){
        rint mid = (l + r) >> 1;
        if(2*(sc[mid]-sc[ql]) <= len) pos = mid,l = mid + 1;
        else r = mid - 1;
    }
    rint x = c[pos];ss[x] = qr-ql;
    if(ql < pos) fa[lc[x] = buildc(ql,pos)] = x;
    if(pos + 1 < qr) fa[rc[x] = buildc(pos+1,qr)] = x;
    return x;
}
int build(rint x){
    rint y = x;
    do for(int v:e[y]) if(v ^ son[y]) fa[build(v)] = y; while(y = son[y]);
    y = 0;
    do c[y++] = x,sc[y] = sc[y-1] + siz[x] - siz[son[x]];while(x = son[x]);
    return buildc(0,y);
}
inline void upd(rint x){
    bool flag = true;rint val = 0;
    while(x){
        sum[x] += val;
        if(flag){
            tag[x]++;
            if(rc[x]) tag[rc[x]]--;
            val += 1 + ss[lc[x]];
            sum[x] -= ss[rc[x]];
        }
        flag = (x ^ lc[fa[x]]);
        if(flag && (x ^ rc[fa[x]])) val = 0;
        x = fa[x];
    }
}
inline int qry(rint x){
    rint res = 0,val = 0;bool flag = true;
    while(x){
        if(flag){
            res += sum[x] - sum[rc[x]];
            res -= ss[rc[x]]*tag[rc[x]];
            val += 1 + ss[lc[x]];
        }
        res += val*tag[x];
        flag = (x ^ lc[fa[x]]);
        if(flag && (x ^ rc[fa[x]])) val = 0;
        x = fa[x];
    }
    return res;
}
inline void solve(){
    base = (base<<64)/mod;
    qcin>>n>>m;
    rint f,l,r,x;
    rep(i,2,n,1){qcin>>f;f++;e[f].eb(i);}
    rep(i,1,m,1){
        qcin>>l>>r>>x;r++;x++;
        if(l) q[++cq] = {i,l,x,0};
        q[++cq] = {i,r,x,1};
    }
    dfs1(1);rep(i,1,n,1) fa[i] = 0;build(1);
    int now = 0;
    sort(q+1,q+1+cq,[](node x,node y){return x.x<y.x;});
    rep(i,1,cq,1){
        while(now < q[i].x) now++,upd(now);
        if(q[i].sgn) ans[q[i].id] += qry(q[i].z);
        else ans[q[i].id] -= qry(q[i].z);
    }
    rep(i,1,m,1) qcout<<Mod(ans[i])<<'\n';
    
}
signed main(){
    // cin.tie(nullptr)->sync_with_stdio(false);
    solve();
}

标签:getch,return,++,LNOI2014,int,str,LCA,buf
From: https://www.cnblogs.com/hzoi-Cu/p/18493742

相关文章

  • 「Day-4 提高笔记-LCA最近公共祖先」
    #include<iostream>usingnamespacestd;constintMAXN=5*1e5+5;structnode{ intto,next;}e[MAXN*2];intf[MAXN][20],dp[MAXN];//f[x][i]表示x的第2^i个节点的编号inth[MAXN*2],tot=0;intn,m,s;voidadd(intx,inty){ e[++tot]={y,h[x]}; h......
  • Cinemachine系列——CinemachineBrain & CinemachineVirtualCamera
    CinemachineBrainCinemachineBrain是Unity摄像机与场景中的Cinemachine虚拟摄像机之间的链接。它监控优先级堆栈以选择当前的虚拟摄像机,并在必要时进行混合。最后,也是最重要的一点,它将虚拟摄像机的状态应用到附加的Unity摄像机上。CinemachineBrain还定义了虚拟摄像机之......
  • LCA学习笔记
    LCA学习笔记定义:在一棵树中,两个节点的最近公共祖先。1.暴力求法处理出每个点的深度,先把深度较深的一个点沿着父节点方向一直走到与另一个点相同的深度,如果此时两个点不同,那么两个点一起向上跳(代码实现过于简单,这里不过多赘述)2.倍增优化暴力注意到我们在暴力求法中,点是一步一......
  • 【模板】最近公共祖先(LCA)倍增
     P3379P3379【模板】最近公共祖先(LCA)#【模板】最近公共祖先(LCA)##题目描述如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。##输入格式第一行包含三个正整数$N,M,S$,分别表示树的结点个数、询问的个数和树根结点的序号。接下来$N-1$行每行包含两个正......
  • 3DRealCar: An In-the-wild RGB-D Car Dataset with 360-degree Views
    3DRealCar:AnIn-the-wildRGB-DCarDatasetwith360-degreeViewsDu,XiaobiaoandSun,HaiyangandWang,ShuyunandWu,ZhuojieandSheng,HongweiandYing 来自很多单位,其中企业所在单位是LiAuto项目地址:https://xiaobiaodu.github.io/3drealcar/ gitcode: h......
  • 倍增 && LCA 杂题
    倍增&&LCA杂题倍增之前没研究过,甚至基础原理搞得都不太懂,只知道背个ST表和LCA的板子,补题补2022CSP发现T4根本学不懂,本来打算不学了,结果NOIP2018还考过类似的。所以补一下这个坑。倍增,字面意思就是成倍增长,这是指我们在进行递推时如果状态空间很大,通常的线性递推......
  • 求 LCA 方法总结
    求LCA方法总结前言求LCA是十分基础的东西,但是方法众多。此篇介绍OI中常用的求法。倍增求LCA蒟蒻最先学的求LCA方法就是倍增求LCA。预处理和查询时间复杂度均为单\(\log\)。优点为好理解,比较简单,且便于处理路径数据。树剖LCA重链剖分。优点是预处理是线性复杂度,......
  • LCA
    \(\color{purple}{1.暴力}\)#include<iostream>#include<bits/stdc++.h>usingnamespacestd;constintmaxn=5e5+10;vector<int>vec[maxn];intf[maxn];intdep[maxn];voiddfs(intnow,intfa);intgt(inta,intb);intmain()......
  • 倍增求 LCA
    1.树上倍增——倍增求LCA    LCA指的是最近的公共祖先,倍增法求解LCA的步骤如下。(1)预处理    a.求深度:对于每个节点dfs预处理处节点深度;    b.  求倍增祖先:计算出每个节点向父元素跳  步所到达的节点(在这里 大于整棵树的最大深度) ......
  • Volcano新版本发布:10大功能提升统一调度和细粒度资源管理能力
    本文分享自华为云社区《Volcanov1.10.0版本正式发布!10大功能全面提升统一调度和细粒度资源管理能力》,作者:云容器大未来 近日,Volcano社区v1.10.0版本[1]正式发布(Branch:release-1.10[2]),此次版本增加了以下新特性:新增队列优先级设置策略支持细粒度的GPU资源共享与回收支持Po......