题目大意:

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

分析:

若根据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. 如何定义StrokeIt手势 常用StrokeIt手势大全

    1 最小化,最大化,最小化所有(显示桌面) 斜向上表示最大化或者还原,斜向下表示最小化,适用于任务管理器和一般应用程序(有这三个按钮的都可以),先斜向下再斜向上表示显示桌面,这个在WIN7系统中不太实 ...

  2. 从Linux 2.6.8内核的一个TSO/NAT bug引出的网络问题排查观点(附一个skb的优化点)

    梦中没有错与对,梦中没有恨和悔...最好闭上你的嘴.这样才算可爱...我不会说:这不公道,我不能接受.我会用朴素的文字记录点点滴滴,早上4点多起来,一气呵成最近的收获与评价,愤慨与忏悔. 四年多前的一 ...

  3. ios method swizzling

      阅读器 iOS开发iOS   本文由TracyYih[博客]翻译自NSHipster的文章Method Swizzling.   在上周associated objects一文中,我们开始探索Ob ...

  4. LeetCode 290. Word Pattern (词语模式)

    Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...

  5. 【bzoj1002】 [FJOI2007]轮状病毒DP

    递推+环状特殊处理+高精度   #include<algorithm> #include<iostream> #include<cstdlib> #include& ...

  6. 一次次迭代 百度语音生成 api 字幕 语音的同步性 关键

    发音字符 数一样 D:\myv\semHAND9myuid1523961381.avi 0.7053863117786668 --------------- 深圳市雅超服饰有限公司是一家专业设计制作高 ...

  7. Codeforces Round #313 A. Currency System in Geraldion(简单题)

    A. Currency System in Geraldion time limit per test 2 seconds memory limit per test 256 megabytes in ...

  8. XHR ajax

    谷歌搜索xhr site:cnblogs.com https://www.cnblogs.com/xiaohuochai/p/6036475.html 在Chrome的network监视中,类型为XH ...

  9. C# 数组转换为DataTable 的三个方法

    C# 数组转换为DataTable 的三个方法   using System; using System.Data; namespace ArrayToDataTable { class ArrayT ...

  10. openStack Packages yum upgrade

    依赖关系解决 ============================================================================================= ...