CF176E Archaeology(set用法提示)
题目大意:
给一棵树,每次激活或熄灭一个点,每次问这些点都联通起来所需的最小总边权
分析:
若根据dfs序给所有点排序,为$v1,v2,v3....vk$,那么答案就是$(dis(v1,v2)+dis(v2,v3)+...+dis(vk-1,vk)+dis(vk,v1))/2$
只需要动态的维护这个序列,每次拿出前后两个点后用lca修改答案即可
这道题主要是想学习一下set在这方面的使用
毕竟现在开O2的题比比皆是,要是能少写个平衡树岂不美哉(我也不会写233
我们就默认使用的是c++11的标准吧
如何为set重载运算符
首先你要有一个结构体,并在里面重载一个bool类型的()函数,先这样(这里以将数字按d数组的大小排序为例):
struct cmp{bool operator () (const int &a,const int &b){return d[a]<d[b];}};
接下来这样声明set:
set<int,cmp>S;
如何查找一个元素的前驱后继等
我们这里声明迭代器时使用c++11特有的auto用法,看起来方便不少(set<int>::iterator)
这里以查找x的前驱后继为例(循环式的,即若x为最后一个数,后继就是第一个数,反过来同理
auto it=S.lower_bound(x),a=it,b=it;
int l=(it==S.begin()?*--S.end():*--a);
int r=(it==--S.end()?*S.begin():*++b);
注意这里end()函数返回的是个超尾,所以要--
这里我们看到迭代器的移动用加减即可,取值时用*即可
插入删除
insert和erase,千万别记错了
S.insert(x);
S.erase(x);
接下来放上这道题的代码
#include<bits/stdc++.h>
#define N 100005
#define ll long long
using namespace std;
int n,q;
int h[N],to[*N],nxt[*N],w[*N],etop;
void add(int a,int b,int c){to[++etop]=b,nxt[etop]=h[a],w[etop]=c,h[a]=etop;}
int fa[N][],d[N],tot,dep[N];
ll len[N][];
void dfs(int u){
d[u]=++tot;
for(int i=;i<=;i++){
fa[u][i]=fa[fa[u][i-]][i-];
len[u][i]=len[u][i-]+len[fa[u][i-]][i-];
if(fa[u][i]==)break;
}
for(int k=h[u],v=to[k];k;k=nxt[k],v=to[k])
if(v!=fa[u][]){
fa[v][]=u;len[v][]=w[k];
dep[v]=dep[u]+;
dfs(v);
}
}
ll LCA(int x,int y){
ll ans=;
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)
if(fa[x][i]&&dep[fa[x][i]]>=dep[y]){
ans+=len[x][i];
x=fa[x][i];
}
if(x==y)return ans;
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i]){
ans+=len[x][i];
ans+=len[y][i];
x=fa[x][i];
y=fa[y][i];
}
ans+=len[x][];
ans+=len[y][];
return ans;
}
struct cmp{bool operator () (const int &a,const int &b){return d[a]<d[b];}};
set<int,cmp>S;
ll ans;
void ins(int x){
S.insert(x);
auto it=S.lower_bound(x),a=it,b=it;
int l=(it==S.begin()?*--S.end():*--a);
int r=(it==--S.end()?*S.begin():*++b);
ans-=LCA(l,r);
ans+=LCA(l,x);
ans+=LCA(x,r);
}
void del(int x){
auto it=S.lower_bound(x),a=it,b=it;
int l=(it==S.begin()?*--S.end():*--a);
int r=(it==--S.end()?*S.begin():*++b);
ans+=LCA(l,r);
ans-=LCA(l,x);
ans-=LCA(x,r);
S.erase(x);
}
char o[];
int main(){
scanf("%d",&n);
for(int i=,a,b,c;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c),add(b,a,c);
}
dfs();
scanf("%d",&q);
while(q--){
scanf("%s",o);
if(o[]=='?')cout<<ans/<<endl;
else{
int x;scanf("%d",&x);
if(o[]=='+')ins(x);
else del(x);
}
}
return ;
}
2019.6.18 update
今天在写一个扫描线题时使用上面的方法重置set的比较符出现了问题,使用lower_bound会在大数据下WA掉,但upper_bound则没问题
如果使用常规的重载运算符的话则两种方式都没问题……(蒙圈ing
这里给个当时的两种比较函数吧
这是出了问题的:
struct cmp{
bool operator () (const hu &A,const hu &B){
double as=A.y+sqrt(A.r*A.r-(A.x-X)*(A.x-X))*(1.0*A.u);
double bs=B.y+sqrt(B.r*B.r-(B.x-X)*(B.x-X))*(1.0*B.u);
if(as+eps>bs&&bs+eps>as)return A.u<B.u;
else return as<bs;
}
};
这个是改成重载运算符的:
bool operator < (const hu &A,const hu &B){
double as=A.y+sqrt(A.r*A.r-(A.x-X)*(A.x-X))*(1.0*A.u);
double bs=B.y+sqrt(B.r*B.r-(B.x-X)*(B.x-X))*(1.0*B.u);
if(as+eps>bs&&bs+eps>as)return A.u<B.u;
else return as<bs;
}
如果哪位大神路过希望能指点一下555(;´д`)ゞ
还有NOI没有C++11
所以跟我一起拼一遍
iterator
再来3遍
iterator
iterator
iterator
ojbk!
CF176E Archaeology(set用法提示)的更多相关文章
- CF176E Archaeology
CF176E Archaeology 有一棵 \(n\) 个点的带权树,每个点都是黑色或白色,最初所有点都是白色的.有 \(m\) 个询问: 把点 \(x\) 从白色变成黑色 把点 \(x\) 从黑色 ...
- group by用法提示:select涉及字段规则
工资表t_salary如下: id month name salary 1 201601 Jim 12 2 201601 Bruce 30 3 201601 Peter 23 ...
- Bootstrap-Plugin:提示工具(Tooltip)插件
ylbtech-Bootstrap-Plugin:提示工具(Tooltip)插件 1.返回顶部 1. Bootstrap 提示工具(Tooltip)插件 当您想要描述一个链接的时候,提示工具(Tool ...
- Bootstrap 提示工具(Tooltip)插件
当您想要描述一个链接的时候,使用提示工具插件是一个不错的选择.Bootstrap提示工具插件做了很多的改进,例如不需要依赖图像,而是改变Css动画效果,用data属性来存储标题信息. 用法 提示工具( ...
- linux工具apt、yum和dnf运用
首先,说明一下我的环境:ubuntu16.04. 什么是APT: 高级包装工具(英语:Advanced Packaging Tools,简称:APT)是Debian及其衍生发行版(如:ubuntu ...
- Linux下的shell编程(三)BY 四喜三顺
正则表达式:-------------------------------------------------------------------------------------------^ ...
- [转]搭建Maven私服
在开发过程中,有时候会使用到公司内部的一些开发包,显然把这些包放在外部是不合适的.另外,由于项目一直在开发中,这些内部的依赖可能也在不断的更新.可以通过搭建公司内部的Maven服务器,将第三方和内部的 ...
- yum 介绍
yum是一个用于管理rpm包的后台程序,用python写成,可以非常方便的解决rpm的依赖关系.在建立好yum服务器后,yum客户端可以通过 http.ftp方式获得软件包,并使用方便的命令直接管理. ...
- [cocos2dx]利用NDK崩溃日志查找BUG
摘要: 在android上开发c++应用, crash日志都是汇编码, 很难对应到c++代码中去. 通过此文, 你可以定位到程序崩溃时的C++代码, 精确查找问题. 博客: http://www.cn ...
随机推荐
- 46.Android 自己定义Dialog
46.Android 自己定义Dialog Android 自己定义Dialog 前言 提示Dialog 提示Dialog 效果图 菜单Dialog 菜单Dialog 效果图 DialogActivi ...
- C++学习之extern "C"
我们知道,extern关键字可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.这里起到的是声明作用范围的用处.另外,extern还可以与 ...
- Fedora下克隆Octopress博客
我在自己的github上搭建了一个Octopress博客(http://songlee24.github.io/),用于不定期的写一些学习笔记和心得体会.但是有时候由于换了电脑或者重装了linux系统 ...
- scikit-learn:4.7. Pairwise metrics, Affinities and Kernels
參考:http://scikit-learn.org/stable/modules/metrics.html The sklearn.metrics.pairwise submodule implem ...
- ASP.NET Overview
https://msdn.microsoft.com/en-us/library/4w3ex9c2.aspx ASP.NET is a unified统一的 Web development model ...
- go语言笔记——切片底层本质是共享数组内存!!!绝对不要用指针指向 slice切片本身已经是一个引用类型就是指针
切片 切片(slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型) ...
- 【转】webview的几个问题
我们在native与网页相结合开发的过程中,难免会遇到关于WebView一些共通的问题.就我目前开发过程中遇到的问题以及最后得到的优化方案都将在这里列举出来.有些是老生常谈,有些则是个人摸索得出解决方 ...
- bzoj 3944 Sum —— 杜教筛
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3944 杜教筛入门题! 看博客:https://www.cnblogs.com/zjp-sha ...
- bzoj4082
贪心+倍增 首先如果这个问题在序列上,好像可以按右端点排序,然后从起点开始向能到的最远的地方走. 但是环上不可以,因为随即一个起点可能不是最小的. 然后神思路来了:我们先将环展开倍增,再将区间按右端点 ...
- Android 数据库
官方文档:https://developer.android.com/training/basics/data-storage/databases.html#WriteDbRow 原帖:http:// ...