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 ...
随机推荐
- Leet Code OJ 26. Remove Duplicates from Sorted Array [Difficulty: Easy]
题目: Given a sorted array, remove the duplicates in place such that each element appear only once and ...
- leetcode第一刷_Spiral Matrix
我认为这个题好无聊啊,好端端一个数组.干嘛要跟比巴卜一样转一圈输出呢. . 思想非常easy,每次从左到右.再从上到下,在从右到左,再从下到上.问题是每次到什么时候该改变方向.我的做法是用一个变量保存 ...
- cgi程序读取post发送的特殊字符,尤其适合于微信公众平台开发中发送被动消息
[问题]用c编写cgi程序怎样取出html表单post来的数据? [分析]html表单post来的数据形如username="zhang"&&password=&q ...
- 从新浪微博和MySQL的password保护机制谈HTTPS/SSL的必要性
尽管业界已经达成共识,在传输用户password等须要保密的信息时,尽可能採用HTTPS/SSL协议传输. 但我们还是能够看到少数没实用HTTPS/SSL加密的站点或应用. 新浪微博的登录页面和MyS ...
- 修改RedHat 7.2 进程最大句柄数限制
RedHat对进程打开文件句柄数主要通过设置全局值和登陆用户分别管理.其中/proc/sys/fs下设置全局最大文件句柄数和用户进程能打开的最大文件句柄数,这两个参数一般情况下不需要修改. 对于普通用 ...
- c++ vector数组的定义使用
/* *********************************************** Author :guanjun Created Time :2017/3/18 13:32:52 ...
- IEC61131-3——数据类型
1. 摘要 列出IEC61131-3支持的几种常用数据类型. 2. 内容 使用USB-CAN接口卡调试从站,SDO发送使用的功能码与字节的关系如下. 2f表示8位,2b表示16位,23表示32位数据. ...
- bzoj3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛——递推 / 组合数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 对于这种有点巧妙的递推还是总是没有思路... 设计一个状态 f[i] 表示第 i 位置 ...
- JSP-Runoob:JSP 调试
ylbtech-JSP-Runoob:JSP 调试 1.返回顶部 1. JSP 调试 要测试/调试一个JSP或servlet程序总是那么的难.JSP和Servlets程序趋向于牵涉到大量客户端/服务器 ...
- bzoj3940
AC自动机 复习一下... 可惜又写错了 我们发现就是把单词建成ac自动机,然后把串在ac自动机上跑一遍,每到一个单词结束点就删除,删除是利用栈,每次弹出单词长度个字符就可以了 发现两个小问题,str ...