HDU4467 Graph

题意:

给出一张染色图,\(n\)个点每个点是黑色或者白色,\(m\)条带权边,\(q\)次操作,有两种操作:

  1. 改变一个点的颜色
  2. 问所有边中两个端点的颜色为给定情况的边权和是多少

题解:

首先因为有重边,所以先把重边合并一下

然后按每个点的度数是否大于\(\sqrt{边总数}\),把点分轻点和重点,同时记录所有三种询问情况的答案

在图中,重点我们保存其所有连的重点的边,轻点我们保存其所有连出去的边

显然重点不会超过\(sqrt{边总数}\)个,且重点和轻点所连出去的边不会超过\(sqrt{边总数}\)条

每个重点要记录它连出去的到达黑点的边的总权值和到达白点的边的总权值

对于每次修改操作,分轻重点分别维护

  • 如果修改的是轻点,那么直接暴力修改答案
  • 如果是重点,利用保存的连出去的边到达的两种颜色的权值和更新答案

    同时每次修改一个点,需要更新其连的重点的两个总权值数据

对于查询操作直接输出记录的答案即可

查询复杂度\(O(1)\)

修改复杂度\(O(sqrt{边总数})\)

总时间复杂度为\(O(q sqrt{边总数})\)

只给了\(32MB\)的空间,很容易爆内存

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
typedef long long int LL;
int n,m,col[MAXN],deg[MAXN];
LL vtot[3],val[2][MAXN];
bool heavy[MAXN];
vector<pair<int,LL>> G[MAXN];
char op[10];
void solvequery(){
scanf("%s",op);
if(op[0]=='A'){
int x, y;
scanf("%d %d",&x,&y);
printf("%I64d\n",vtot[x+y]);
}
else{
int x; scanf("%d",&x);
if(heavy[x]){
vtot[1+col[x]] -= val[1][x]; vtot[0+col[x]] -= val[0][x];
vtot[1+(col[x]^1)] += val[1][x]; vtot[0+(col[x]^1)] += val[0][x];
}
else{
for(auto e : G[x]){
vtot[col[x]+col[e.first]] -= e.second;
vtot[(col[x]^1)+col[e.first]] += e.second;
}
}
for(auto e : G[x]){
if(!heavy[e.first]) continue;
val[col[x]][e.first] -= e.second;
val[col[x]^1][e.first] += e.second;
}
col[x] ^= 1;
}
}
pair<pair<int,int>,LL> vec[MAXN];
void solve(int kase){
for(int i = 1; i <= n; i++){
scanf("%d",&col[i]);
G[i].clear();
val[0][i] = val[1][i] = deg[i] = 0;
}
vtot[0] = vtot[1] = vtot[2] = 0;
int tot = 0;
for(int i = 1; i <= m; i++){
int u, v, w; scanf("%d %d %d",&u,&v,&w);
if(u>v) u ^= v ^= u ^= v;
vec[++tot] = make_pair(make_pair(u,v),w);
}
sort(vec+1,vec+1+tot);
int nt = 1;
for(int i = 2; i <= tot; i++){
if(vec[i].first==vec[nt].first) vec[nt].second += vec[i].second;
else vec[++nt] = vec[i];
}
for(int i = 1; i <= nt; i++) deg[vec[i].first.first]++, deg[vec[i].first.second]++;
int up = sqrt(nt);
for(int i = 1; i <= n; i++) heavy[i] = deg[i]>=up;
for(int i = 1; i <= nt; i++){
auto &e = vec[i];
int u = e.first.first, v = e.first.second;
LL w = e.second;
if(heavy[u]){
if(heavy[v]) G[u].push_back(make_pair(v,w));
val[col[v]][u] += w;
}
else G[u].push_back(make_pair(v,w));
if(heavy[v]){
if(heavy[u]) G[v].push_back(make_pair(u,w));
val[col[u]][v] += w;
}
else G[v].push_back(make_pair(u,w));
vtot[col[u]+col[v]] += w;
}
int q; scanf("%d",&q);
printf("Case %d:\n",kase);
while(q--) solvequery();
}
int main(){
int kase = 0;
while(scanf("%d %d",&n,&m)!=EOF) solve(++kase);
return 0;
}

HDU4467 Graph【轻重点维护】的更多相关文章

  1. HDU4467:Graph(点的度数分块)

    传送门 题意 给出一张n个点m条边的无向图,点的颜色为0/1,每次有两种操作: 1.Asksum x y,查询两点颜色为x和y的边的权值之和 2.Change x,将x颜色取反 分析 最直接的做法是每 ...

  2. hdu4467 Graph

    Graph Problem Description P. T. Tigris is a student currently studying graph theory. One day, when h ...

  3. Nebula Graph 在企查查的应用

    本文首发于 Nebula Graph Community 公众号 背景 企查查是企查查科技有限公司旗下的一款企业信用查询工具,旨在为用户提供快速查询企业工商信息.法院判决信息.关联企业信息.法律诉讼. ...

  4. 2013 ACM/ICPC Asia Regional Online —— Warmup2

    HDU 4716 A Computer Graphics Problem 水题.略 HDU 4717 The Moving Points 题目:给出n个点的起始位置以及速度矢量,问任意一个时刻使得最远 ...

  5. scala知识点(一)

    1.drop,dropRight,dropWhile drop: drop(n: Int): List[A] 丢弃前n个元素,返回剩下的元素 dropRight: dropRight(n: Int): ...

  6. GraphX 图数据建模和存储

    背景 简单分析一下GraphX是怎么为图数据建模和存储的. 入口 能够看GraphLoader的函数. def edgeListFile( sc: SparkContext, path: String ...

  7. [Docker01] The Docker Road

    The Docker Road Docker是什么? Docker是docker容器为资源分隔和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员设计的,用于构建,发布和运行分布式应用的平台 ...

  8. [源码解析] Pytorch 如何实现后向传播 (2)---- 引擎静态结构

    [源码解析] Pytorch 如何实现后向传播 (2)---- 引擎静态结构 目录 [源码解析] Pytorch 如何实现后向传播 (2)---- 引擎静态结构 0x00 摘要 0x01 Engine ...

  9. 转债---Pregel: A System for Large-Scale Graph Processing(译)

    转载:http://duanple.blog.163.com/blog/static/70971767201281610126277/   作者:Grzegorz Malewicz, Matthew ...

随机推荐

  1. Windows软件Everything的配置

    Everything配置 Everything是一款Windows下的搜索软件,怎么安装应该不难.这里说一下个人使用的两个习惯. 主要就两点,一个是快捷键,一个是搜索路径 1. 快捷键 配置快捷键,点 ...

  2. 剑指offer 面试题10.2:青蛙变态跳台阶

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级--它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 编程思想 因为n级台阶,第一步有n种跳法:跳1级.跳2级.到跳n级跳1级,剩下 ...

  3. CTF实验吧-WEB题目解题笔记(1)简单的登陆题

    1.简单的登陆题 解题链接: http://ctf5.shiyanbar.com/web/jiandan/index.php  Burp抓包解密 乱码,更换思路.尝试id intruder 似乎也没什 ...

  4. 小试牛刀ElasticSearch大数据聚合统计

    ElasticSearch相信有不少朋友都了解,即使没有了解过它那相信对ELK也有所认识E即是ElasticSearch.ElasticSearch最开始更多用于检索,作为一搜索的集群产品简单易用绝对 ...

  5. REUSE_ALV_FIELDCATALOG_MERGE函数

    今天使用REUSE_ALV_FIELDCATALOG_MERGE函数,就是获取不到fieldcat, 搞了半天才发现,原来参数要全部大写才行!!小写字符就是获取不到,唉,悲哀...

  6. C++ STL 优先队列 (priority_queue)

    std::priority_queue <queue> 优先队列   优先队列是一种容器适配器,根据某些严格的弱排序标准,使其第一个元素始终包含的最大元素.   这种特性类似于堆,它可以在 ...

  7. ASP.NET Core错误处理中间件[4]: 响应状态码页面

    StatusCodePagesMiddleware中间件与ExceptionHandlerMiddleware中间件类似,它们都是在后续请求处理过程中"出错"的情况下利用一个错误处 ...

  8. linux下删除文件夹及下面所有文件

    使用rm -rf 目录名字 命令即可 -r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思 rm 不带参数 只能删除文件 rm test.txt mkdir /us ...

  9. bootstrap 后端模板

    Twitter Bootstrap 框架已经广为人知,用于加快网站,应用程序或主题的界面开发,并被公认为是迄今对于 Web 开发的最有实质性帮助的工具之一.在此之前的,各种各样的界面库伴随着高昂的维护 ...

  10. linux串口编程

    按照对linux系统的理解,串口编程的顺序无非就是open,read,write,close,而串口有波特率.数据位等重要参数需要设置,因此还应该用到设置函数,那么接下来就带着这几个问题去学习linu ...