C138 线段树分治 P2056 [ZJOI2007] 捉迷藏

news/2024/9/30 23:39:12

视频链接:C138 线段树分治 P2056 [ZJOI2007] 捉迷藏_哔哩哔哩_bilibili

 

 

 

P2056 [ZJOI2007] 捉迷藏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 线段树分治 O(nlognlogn)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <bitset>
using namespace std;#define ls (i<<1)
#define rs (i<<1|1)
#define mid ((l+r)>>1)
const int N=500005;
int n,q;
int head[N],ne[N<<1],to[N<<1],idx;
void add(int u,int v){to[++idx]=v;ne[idx]=head[u];head[u]=idx;
}
int fa[N],son[N],dep[N],siz[N],top[N];void dfs1(int u,int f){ //搞fa,son,depfa[u]=f;siz[u]=1;dep[u]=dep[f]+1;for(int i=head[u];i;i=ne[i]){int v=to[i];if(v==f) continue;dfs1(v,u);siz[u]+=siz[v];if(siz[son[u]]<siz[v])son[u]=v;}
}
void dfs2(int u,int t){ //搞toptop[u]=t;  //记录链头if(son[u])dfs2(son[u],t);//搜重儿子for(int i=head[u];i;i=ne[i]){int v=to[i];if(v==fa[u]||v==son[u])continue;dfs2(v,v); //搜轻儿子
  }
}
int lca(int u,int v){while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);u=fa[top[u]];}return dep[u]<dep[v]?u:v;
}int lst[N];    //上次出现的时刻
bitset<N> col; //黑色=0
bitset<N> qb;  //查询=1
vector<int> tr[N<<2];   //节点
stack<pair<int,int>>st; //
int u,v,ans[N];void insert(int i,int l,int r,int L,int R,int x){if(L>r||R<l) return;if(L<=l&&r<=R) return tr[i].push_back(x);insert(ls,l,mid,L,R,x);insert(rs,mid+1,r,L,R,x);
}
int dis(int x,int y){ //两点距离return dep[x]+dep[y]-2*dep[lca(x,y)];
}
void solve(int i,int l,int r){auto now=st.size();for(int x:tr[i]){st.push({u,v}); //旧直径入栈if(!u&&!v) u=x,v=x;else{int d0=dis(u,v),d1=dis(u,x),d2=dis(v,x);int d=max(d0,max(d1,d2));if(d1==d) v=x;else if(d2==d) u=x; //更新直径端点
    }}if(l==r) ans[l]=(!u||!v)?-1:dis(u,v);else solve(ls,l,mid),solve(rs,mid+1,r);while(st.size()!=now){ //撤销auto t=st.top();u=t.first,v=t.second;st.pop();}
}
int main(){ios::sync_with_stdio(false);cin>>n;for(int i=1,u,v;i<n;i++){cin>>u>>v; add(u,v);add(v,u);}dfs1(1,0);dfs2(1,0); //树链剖分for(int i=1;i<=n;i++) lst[i]=1;cin>>q;for(int i=1,x;i<=q;i++){ //操作为时间轴char c; cin>>c;if(c=='C'){cin>>x;if(!col[x]){ //黑色=0col[x]=1;insert(1,1,q,lst[x],i,x); //插入x的出现时间
      }else col[x]=0,lst[x]=i; //记录x再次出现时刻
    }else qb[i]=1; //i时刻是查询
  }for(int i=1;i<=n;i++) //插入i的出现时间if(!col[i]) insert(1,1,q,lst[i],q,i);solve(1,1,q);for(int i=1;i<=q;i++)if(qb[i])printf("%d\n",ans[i]);
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/45095.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

[lnsyoj118/luoguP3369]普通平衡树

平衡树 Treap题意 维护一个数据结构,要求支持插入,删除,根据排名查数,根据数查排名,查询前驱,查询后继\(6\)个操作 sol 考虑到后四个查询的操作,会发现使用二叉搜索树(BST)完全可以实现 为了完成这四个操作,需要在每个节点记录\(3\)个值:\(key\) 表示当前节点的数 \(c…

牛客周赛46(思路待补)

比赛链接:牛客周赛46赛时感受 本场参加的是内测,多亏了内测群的佬提供的思路,得以AK。 ABC都是简单的签到题,D稍微需要分类一下,EF有点算法知识,E可以使用前缀和+二分搜索过掉,但是听说好像还能使用离散化树状数组等等,F是数学知识,隔板法和求质数、求组合…

[TinyRenderer] Chapter1 p3 Line

(注:本小节不是对划线算法事无巨细的证明,如果你需要更加系统的学习,请跳转至文末的参考部分) 如果你是一名曾经学习过图形学基础的学生,那么你一定对画线算法稔熟于心,中点划线算法,Bresenham算法。其中,现代光栅化器中使用最多的就是Bresenham算法,它以去除了除法和…

3个月搞定计算机二级C语言!高效刷题系列进行中

前言 大家好,我是梁国庆。 计算机二级应该是每一位大学生的必修课,相信很多同学的大学flag中都会有它的身影。 我在大学里也不止一次的想要考计算机二级office,但由于种种原因,备考了几次都不了了之。 这一次我想换个目标! 备考计算机二级C语言 今天山东省考试院发布了关于…

讯飞有一个可以根据描述文本自动生成PPT的AI接口,有趣

文档:https://www.xfyun.cn/doc/spark/PPTGeneration.html 价格方面提供了免费1000点的额度,生成一次是10点,正好100次,如果要购买的话最低要购买1344元的,没有按量付费的模式,个人小开发者可买不起。 让我们跑起来玩玩,官方提供了python的sdk,下载到本地: 不想下载sd…

RSS 解析:全球内容分发的利器及使用技巧

RSS(Really Simple Syndication)是一种 XML 格式,用于网站内容的聚合和分发,让用户能快速浏览和跟踪更新。RSS 文档结构包括 `<channel>` 和 `<item>` 元素,允许内容创作者分享标题、链接和描述。通过 RSS,用户可以定制新闻源,过滤不相关信息,提高效率。RS…

2024.6.10漏洞探针

探针(扫描器) 1、nmap漏洞库,根目录下scripts中调用2、Goby(红队版) 直接输入ip扫描资产,漏洞库较少; 3、Nessus 本地安装: 下载安装普通版;注册获取验证码; 注册用户 nessus,nessus123 漏洞利用 1、工具框架 metasploit和searchsploit 忍者系统可以一键使用msf;2、…

6.12Web应用漏洞发现探针利用

已知CMS、开发框架、 思路: 各个页面查看数据包(地址信息),查看框架,上fofa关键字搜索(查看其框架信息如thinkhphp),利用检测工具测试漏洞情况; 网站根目录下的robots.txt文件信息; /data/admin/ver.txt 网站升级时间; 常见SQL注入、登录、逻辑越权支付逻辑绕过思路:…