题目大意:

给一棵树,每次激活或熄灭一个点,每次问这些点都联通起来所需的最小总边权

分析:

若根据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用法提示)的更多相关文章

  1. CF176E Archaeology

    CF176E Archaeology 有一棵 \(n\) 个点的带权树,每个点都是黑色或白色,最初所有点都是白色的.有 \(m\) 个询问: 把点 \(x\) 从白色变成黑色 把点 \(x\) 从黑色 ...

  2. group by用法提示:select涉及字段规则

    工资表t_salary如下:  id month  name  salary  1 201601  Jim  12  2 201601  Bruce  30  3 201601  Peter  23 ...

  3. Bootstrap-Plugin:提示工具(Tooltip)插件

    ylbtech-Bootstrap-Plugin:提示工具(Tooltip)插件 1.返回顶部 1. Bootstrap 提示工具(Tooltip)插件 当您想要描述一个链接的时候,提示工具(Tool ...

  4. Bootstrap 提示工具(Tooltip)插件

    当您想要描述一个链接的时候,使用提示工具插件是一个不错的选择.Bootstrap提示工具插件做了很多的改进,例如不需要依赖图像,而是改变Css动画效果,用data属性来存储标题信息. 用法 提示工具( ...

  5. linux工具apt、yum和dnf运用

      首先,说明一下我的环境:ubuntu16.04. 什么是APT: 高级包装工具(英语:Advanced Packaging Tools,简称:APT)是Debian及其衍生发行版(如:ubuntu ...

  6. Linux下的shell编程(三)BY 四喜三顺

    正则表达式:-------------------------------------------------------------------------------------------^   ...

  7. [转]搭建Maven私服

    在开发过程中,有时候会使用到公司内部的一些开发包,显然把这些包放在外部是不合适的.另外,由于项目一直在开发中,这些内部的依赖可能也在不断的更新.可以通过搭建公司内部的Maven服务器,将第三方和内部的 ...

  8. yum 介绍

    yum是一个用于管理rpm包的后台程序,用python写成,可以非常方便的解决rpm的依赖关系.在建立好yum服务器后,yum客户端可以通过 http.ftp方式获得软件包,并使用方便的命令直接管理. ...

  9. [cocos2dx]利用NDK崩溃日志查找BUG

    摘要: 在android上开发c++应用, crash日志都是汇编码, 很难对应到c++代码中去. 通过此文, 你可以定位到程序崩溃时的C++代码, 精确查找问题. 博客: http://www.cn ...

随机推荐

  1. 中文在C/C++中的处理和汉字乱码问题(wchar_t)

    中文字在C/C++中的处理 现在编程的语言和编程环境随着中国的发展開始对中文有进一步的支持.可是对中文的支持整体来说是有缺陷的,并且有与编译环境的不同导致中文在当前的C/C++中有非常多问题,并且非常 ...

  2. STL源代码剖析(二) - 迭代器与traits技法

    提要 先看一段用迭代器的代码: int a[] = {1, 2, 3, 4, 5}; vector<int> v1( a, a+5); vector<int>::iterato ...

  3. cocos2d-x之android编译环境搭建(第二篇)[版本号:cocos2d-x-3.1.1]

    基于 Android NDK 的学习之旅-----环境搭建 工欲善其事 必先利其器 , 以下介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android 开发 ...

  4. mac 下安装caffe(一)

    1.brew install --build-from-source -vd boost boost-python 这一步出错:libtool: unrecognized option `-stati ...

  5. B1090 [SCOI2003]字符串折叠 区间dp

    又一道区间dp,和上一篇类似,但是比他简单,这个只有两种转移方法,不是很复杂.直接判断是否为重复的串就行. 题干: Description 折叠的定义如下: . 一个字符串可以看成它自身的折叠.记作S ...

  6. JSP-Runoob:JSP 发送邮件

    ylbtech-JSP-Runoob:JSP 发送邮件 1.返回顶部 1. JSP 发送邮件 虽然使用JSP实现邮件发送功能很简单,但是需要有JavaMail API,并且需要安装JavaBean A ...

  7. Systick 更新

    之前写的systick_config(loadvalue) 根据系统时钟为72Mhz来写的,如果system clock不是72MHz怎么办? 重新写了一下,先获取,系统时钟频率. //参数为ms v ...

  8. Spark 机器学习 ---Word2Vec

    package Spark_MLlib import org.apache.spark.ml.feature.Word2Vec import org.apache.spark.sql.SparkSes ...

  9. E20170624-ts

    stateless adj. 无国家的,无国籍的; groupware 群件 cookie  n. 饼干; 小甜点; 吸引人的年轻妇女; 甜面包; session  n. 开会,会议; (法庭的) 开 ...

  10. cropbox

    今天给大家分享一款基于jQuery头像裁剪插件cropbox,这是一款简单实用的jQuery头像在线裁剪插件.该插件适用于适用浏览器:IE8.360.FireFox.Chrome.Safari.Ope ...