Graph HDU - 4467
https://vjudge.net/problem/HDU-4467
大概就是,设一个块大小T
对于度数<=T的点,设为1类点,在改变颜色的时候暴力查询与其相邻点,更新答案
对于度数>T的点,设为2类点,分别维护与其相邻的颜色为0/1的点之间的边权和(记录与每个点相连的所有2类点,然后在任意点(注意2类点也要)改变颜色时维护一下与其相连2类点的这个值),改变颜色的时候根据维护的值O(1)可以计算出对答案的修改
说的再简单一点,1类点由自身去更新其他,2类点由其他去更新自身。。复杂度很容易发现是根号级别的(T=sqrt(m))
但是要注意,重边一定要去。。。不然可以被卡到$n^2$
错误记录:
1.没有在改变2类点颜色时改变相连其他2类点维护的值
2.没有去重边
3.d[a],d[b]和a,b没有极其仔细地区分
//#pragma GCC optimize(3)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
#include<map>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define N 100000
struct E
{
int to,nxt;ll d;
}e[*N+];
int f1[N+],ne;
int TT,n,m,mm,d[N+];
int in[N+],sz,q;
//1类点:in[i]<=sz;2类点:in[i]>sz
ll a1[N+][];
//a1[i][j]:i为2类点,i与相邻的颜色为j的点之间的所有边的权值和
//int num[100100];
char tmp[];
vector<int> ss[N+];//ss[i]:i点到相邻的2类点的边
ll ans[];//ans[0]:00边答案;ans[1]:11边答案;ans[2]:01边答案
map<pii,pii> ma;
ll &gg(int a,int b)
{
if(a==&&b==) return ans[];
if(a==&&b==) return ans[];
return ans[];
}
int main()
{
int a,b,c,i,k;pii t;
while(scanf("%d%d",&n,&m)==)
{
TT++;mm=;//num[0]=0;
memset(f1,,sizeof(f1));ne=;ma.clear();
memset(in,,sizeof(in));ans[]=ans[]=ans[]=;
memset(a1,,sizeof(a1));
for(i=;i<=n;i++) scanf("%d",&d[i]);
for(i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(a>b) swap(a,b);
if(ma.count(mp(a,b)))
{
t=ma[mp(a,b)];
e[t.fi].d+=c;e[t.se].d+=c;
}
else
{
e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;e[ne].d=c;
e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;e[ne].d=c;
in[a]++;in[b]++;
ma[mp(a,b)]=mp(ne-,ne);mm++;
}
gg(d[a],d[b])+=c;
}
sz=sqrt(*mm);
for(i=;i<=n;i++)
if(in[i]>sz)
{
//num[++num[0]]=i;
for(k=f1[i];k;k=e[k].nxt)
a1[i][d[e[k].to]]+=e[k].d;
}
for(i=;i<=n;i++)
{
ss[i].clear();
for(k=f1[i];k;k=e[k].nxt)
if(in[e[k].to]>sz)
ss[i].pb(k);
}
scanf("%d",&q);
printf("Case %d:\n",TT);
while(q--)
{
scanf("%s",tmp);
if(tmp[]=='A')
{
scanf("%d%d",&a,&b);
printf("%lld\n",gg(a,b));
}
else
{
scanf("%d",&a);
if(in[a]<=sz)
{
for(k=f1[a];k;k=e[k].nxt)
{
b=e[k].to;
gg(d[a],d[b])-=e[k].d;
if(in[b]>sz) a1[b][d[a]]-=e[k].d;
}
d[a]^=;
for(k=f1[a];k;k=e[k].nxt)
{
b=e[k].to;
gg(d[a],d[b])+=e[k].d;
if(in[b]>sz) a1[b][d[a]]+=e[k].d;
}
}
else
{
for(i=;i<ss[a].size();i++)
a1[e[ss[a][i]].to][d[a]]-=e[ss[a][i]].d;
gg(d[a],)-=a1[a][];gg(d[a],)-=a1[a][];
d[a]^=;
gg(d[a],)+=a1[a][];gg(d[a],)+=a1[a][];
for(i=;i<ss[a].size();i++)
a1[e[ss[a][i]].to][d[a]]+=e[ss[a][i]].d;
}
}
}
}
return ;
}
Graph HDU - 4467的更多相关文章
- hdu 4467 Graph
P. T. Tigris is a student currently studying graph theory. One day, when he was studying hard, GS ap ...
- HDU 4467 Graph(图论+暴力)(2012 Asia Chengdu Regional Contest)
Description P. T. Tigris is a student currently studying graph theory. One day, when he was studying ...
- HDU 4467 分块
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4467 题意:给定n个点m条边的无向图,点被染色(黑0/白1),边带边权.然后q个询问.询问分为两种: ...
- Bipartite Graph hdu 5313 bitset 并查集 二分图
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5313 题意: 给出n个顶点,m条边,问最多添加多少条边使之构成一个完全二分图 存储结构: bitset ...
- The Shortest Path in Nya Graph HDU - 4725
Problem Description This is a very easy problem, your task is just calculate el camino mas corto en ...
- B - Rikka with Graph HDU - 5631 (并查集+思维)
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some mat ...
- AC日记——The Shortest Path in Nya Graph hdu 4725
4725 思路: 拆点建图跑最短路: 代码: #include <cstdio> #include <cstring> #include <iostream> #i ...
- Rikka with Graph hdu 6090
题解:考虑贪心地一条一条边添加进去. 当 m \leq n-1m≤n−1 时,我们需要最小化距离为 nn 的点对数,所以肯定是连出一个大小为 m+1m+1 的联通块,剩下的点都是孤立点.在这个联通块中 ...
- 7.11 NOI模拟赛 graph 生成函数 dp 多项式
LINK:graph HDU题库里的原题 没做过自闭. 考虑dp 设\(f_{i,j}\)表示前i个点构成j个联通块是树的方案数. 对于一次询问答案即为\(\sum_{j}f_{n,j}j^k\) 考 ...
随机推荐
- Redis 脚本及其应用
参考:http://www.runoob.com/redis/redis-scripting.html Redis 脚本使用 Lua 解释器来执行脚本. Reids 2.6 版本通过内嵌支持 Lua ...
- uboot 对 FAT 分区的解析
uboot 对 FAT 分区的解析 改写 UBOOT 从 U 盘读入固件,然后刷机.发现有的 U 盘无法正确读到分区,跟踪了一下发现自己写的代码有漏洞,只尝试解析分区表里的第一个分区.跟踪的过程中重温 ...
- PandoraBox 支持3G无线上网卡(联通卡3G卡)(一)
一:笔者采用的是系统是OpenWrt之PandoraBox,内核版本3.3.8:硬件设备是MTK的7620开发板. 其中怎么搭建openwrt开发环境在此不用多说,因为既然想实现3G无线上网卡拨号上网 ...
- java面试题(摘录)
1.抽象,继承,封装,多态 2.基本数据类型的字节数 byte:1.int:4.char:2.long:8.float:4.double:8.boolean:1 和short:2 3.String , ...
- Linux 内核源码中likely()和unlikely()【转】
本文转载自:http://blog.csdn.net/tigerjibo/article/details/8279183 ikely()与unlikely()在2.6内核中,随处可见,那为什么要用它们 ...
- java多线程实现简单队列
1.创建Queue.java public class Queue { private LinkedList<Object> list = new LinkedList<Object ...
- Oracle:手工建库
今天学习了小布老师的手工建库视频,自己也做了一遍,下面是创建过程记录: 本地环境oracle10.2.0.1 一.前期准备工作 1.设置环境变量 [oracle@app dbs]$ vi bbk.en ...
- cassandra复制到一个新机器编译失败的问题
在A机器上ant编译后,复制到B机器,在B机器上编译会出错. 原因是载入一些文件时出错,因为路径还是A机器上的路径. 经过与git上的源代码对比,发现多了一个build文件夹,这可能是ant生成的目录 ...
- java回调机制及其实现
1. 什么是回调函数 回调函数,顾名思义,用于回调的函数.回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数.回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机.回调 ...
- [SHOI 2013] 发微博
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4419 [算法] 用std :: set维护每个人的好友集合 当两人成为好友时将每人接 ...