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 ...
随机推荐
- 如何将PSD批量装换为JPG如何对PSD批量减小体积
1 将PSD批量转换为JPG等格式图片方法(注意选中图片之后要点击Add或者Add all把他们放到下面的窗口) 2 转换完成效果如图所示 3 想要批量修改大小,就要使用ACDSee这个软件了 ...
- 如何让图片开口说话 3DMeNow教程
菜鸟玩3D--3DmeNow初级教程 3D软件对于我们这些菜鸟来说,一直是可望而不可及的一种东西,深奥的3D建模,复杂的面板操作--都使我们对之望而却步,有没有一种很简单的3D造型软件,使我们这些菜鸟 ...
- Android实现一个自己定义相机的界面
我们先实现拍照button的圆形效果哈.Android开发中,当然能够找美工人员设计图片,然后直接拿进来.只是我们能够自己写代码实现这个效果哈.最经常使用的的是用layout-list实现图片的叠加, ...
- jdk1.6下使用sardine和jackrabbit-webdav的问题
同步一个遇到的问题,前几天,客户给了一个server地址和usernamepassword.让把上面的文件,download到还有一台server上.我查了下,发现该server使用文件协议是webd ...
- swift手记-6
// // ViewController.swift // learn // // Created by myhaspl on 16/1/26. // Copyright (c) 2016年 myha ...
- Oracle行转列,列转行,行列相互转换
1.行转列 SELECT WM_CONCAT(COLUMN_NAME) COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME = 'T_CREATE_T ...
- TGraphicControl和TCustomControl自绘过程的理论解释
TGraphicControl = class(TControl) // 这个类实在是简单,因为所有事情都已经委托给它的父Win控件了,只要管自己即可 private FCanvas: TCanvas ...
- 推荐微软Windows 8 Metro应用开发虚拟实验室
Kevin Fan分享开发经验,记录开发点滴 推荐微软Windows 8 Metro应用开发虚拟实验室 2012-07-19 05:23 by jv9, 1940 阅读, 4 评论, 收藏, 编辑 微 ...
- C#在WinForm中使用WebKit传递js对象实现与网页交互的方法
这篇文章主要介绍了C#在WinForm中使用WebKit传递js对象实现与网页交互的方法,涉及针对WebBroswer控件及WebKit控件的相关使用技巧,需要的朋友可以参考下 本文实例讲述了C#在W ...
- [luogu_U15118]萨塔尼亚的期末考试
https://zybuluo.com/ysner/note/1239615 题面 \(T\)次询问,求出\[\sum_{i=1}^n\frac{i}{\frac{n(n+1)}{2}}fib_i\] ...