https://vjudge.net/problem/HDU-6756

题目大意:给你一个无向图,每个点有权值a,将f(u)定义为对u的邻居的集合求mex;

有两个操作:

1:将u的权值修改为x

2:查询f(u)

数据量在1e5,可以考虑分块,我们按照每个点的度数将点分为大小点,小于sqrt(n)的为小点,否则为大点。

先预处理分块。

修改操作:

如果为小点,则直接修改他的所有邻居

如果为大点,我们就先不修改他的邻居,我们使用一个容器来记录大点的邻居(大点不会很多的)的当前贡献,等到在查询的时候,我们会先遍历一遍大点的邻居,如果邻居当前的贡献不等于邻居现在的权值的话,说明该大点邻居已经被修改过了,那么我们直接修改该邻居的贡献。

查询操作:直接分块查询mex,先查询每个快是不是满了,不满的话说明答案就在这个块中。

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <cstdlib>
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(a) ((a)&-(a))
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
#define fi first
#define sc second
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define ac cout<<ans<<"\n"
#define pb push_back
using namespace std;
typedef long long  ll;
typedef unsigned long long  ull;
typedef pair<ll,ll> pii;
int dx[4]= {-1,1,0,0},dy[4]= {0,0,1,-1};
const ll mod=1e9+7;
const ll N =1e5+10;
const ll M =250000;
const double eps = 1e-4;
//const double pi=acos(-1);
ll qk(ll a,ll b){ll ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b/=2;}return ans%mod;}
int a[N],block_size=0;
vector<int> g[N];
vector<int>tag[N],cnt[N];
vector<pii>big_n[N];
int n,m;
int du[N];
void _insert(int u,int sum){if(sum>du[u]) sum=du[u]+1;//答案不会超过他的度数cnt[u][sum]++;if(cnt[u][sum]==1) tag[u][sum/block_size]++;
}
void _del(int u,int sum){if(sum>du[u]) sum=du[u]+1;cnt[u][sum]--;if(cnt[u][sum]==0) tag[u][sum/block_size]--;
}
void build(){for(int i=1;i<=n;i++){cnt[i].resize(du[i]+2);//每个点块内的大小tag[i].resize(du[i]/block_size+2);//每个点快的数量for(int v:g[i]){if(du[v]>block_size){big_n[i].push_back({v,a[v]});//记录大点邻居}_insert(i,a[v]);}}
}
int q1(int u){for(int i=0;i<=du[u]/block_size;i++){//分块查询int k=tag[u][i];if(k==block_size) continue;for(int j=i*block_size;j<i*block_size+block_size;j++){if(!cnt[u][j]) return j;}}
}
void sovle(){scanf("%d%d",&n,&m);block_size=sqrt(n);for(int i=1;i<=n;i++) scd(a[i]);for(int i=1;i<=m;i++){int u,v;scdd(u,v);g[u].push_back(v);g[v].push_back(u);du[u]++;du[v]++;}build();int q;scd(q);//cout<<1<<endl;while(q--){int x, u;scanf("%d%d",&x,&u);if(x==1){int k;scanf("%d",&k);if(du[u]<=block_size){//小点直接修改for(int v:g[u]){_del(v,a[u]);_insert(v,k);}}a[u]=k;}else {for(pii &v:big_n[u]){//先查询大点邻居的值是否改变。if(a[v.fi]!=v.se){_del(u,v.se);_insert(u,a[v.fi]);v.se=a[v.fi];}}printf("%d\n",q1(u));}}for(int i=1;i<=n;i++) g[i].clear(),big_n[i].clear(),tag[i].clear(),cnt[i].clear(),du[i]=0;
}
int main()
{
#ifdef LOCALfreopen("in.txt", "r", stdin);
#else//iosint t=1;cin>>t;while(t--) sovle();
#endif // LOCALreturn 0;
}

HDU - 6756 Finding a MEX-分块思想相关推荐

  1. HDU多校1 - 6756 Finding a MEX(分块+二分+树状数组)

    题目链接:点击查看 题目大意:给出一个 n 个点和 m 条边的无向图,每个点都有一个权值,现在需要执行 q 次操作,每次操作分为两种类型: 1 pos val :将第 pos 个点的权值修改为 val ...

  2. HDU 4414 Finding crosses(搜索)

    题目链接:HDU 4414 Finding crosses [题目大意] 给你一张n*n的图,由o #这两个元素组成,让我们找其中有多少十字架. 十字架由#构成 十字架的纵向长度等于横向长度 , 且这 ...

  3. PAT A1057 分块思想

    使用的就是分块思想,之前写过总结,所以不再赘述: 代码如下: #include<iostream> #include<stdlib.h> #include<stdio.h ...

  4. HDU 6035 Colorful Tree(补集思想+树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 单独考虑 ...

  5. hdu 5511 Minimum Cut-Cut——分类讨论思想+线段树合并

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5511 题意:割一些边使得无向图变成不连通的,并且恰好割了两条给定生成树上的边.满足非树边两段一定在给定生成 ...

  6. hdu_5085_Counting problem(莫队分块思想)

    题目连接:hdu_5085_Counting problem 题意:给你一个计算公式,然后给你一个区间,问这个区间内满足条件的数有多少个 题解:由于这个公式比较特殊,具有可加性,我们考虑讲一个数分为两 ...

  7. hdu 4414 Finding crosses

    http://acm.hdu.edu.cn/showproblem.php?pid=4414 简单枚举 代码: #include <iostream> #include <cstdi ...

  8. HDU 6833 莫比乌斯反演 + 数论分块

    给定下列式子: ∑a1=1n∑a2=1n...∑ax=1n(∏j=1xajk)f(gcd⁡(a1,a2...,ax))⋅gcd⁡(a1,a2...,ax)\sum_{a_1=1}^n\sum_{a_2 ...

  9. HDU 6555 The Fool (整除分块 / 打表找规律)

    大致题意 然后就是判断这个式子是奇数还是偶数. n<=1e9 思路 直接整除分块秒了,但我差点忘记整除分块怎么写. 代码 贴一下小代码块 #include<bits/stdc++.h> ...

最新文章

  1. 上交三月月赛[SJTU] 1106 sudoku
  2. 吴恩达:机器学习毕业后,如何规划职业生涯?
  3. Aurora HDR 2019中文版
  4. NoSQL数据库_Redis
  5. sample solution
  6. 数据结构 思维导图【绪论、线性表、栈、队列和数组、树与二叉树、图、查找、排序】
  7. 面向对象之继承与派生
  8. make menuconfig选择m编译为驱动模块
  9. 常用机器学习算法优缺点及其应用领域
  10. python3学习日志Gui编程
  11. U3D NGUI改变GameObject Activity闪烁的问题
  12. C语言项目-俄罗斯方块
  13. java uuid生成算法_Java生成UUID
  14. 开源三维地球Cesium中如何离线加载卫星影像和高程DEM数据
  15. 栈这种数据结构,不就后进先出?
  16. yocto-poky下目录结构分析
  17. 什么是软件质量?试叙述它与软件可靠性的关系。
  18. 1988年图灵奖--伊万·萨瑟兰简介
  19. 【顺序栈】32 顺序栈ADT模板简单应用算法设计:火车调度
  20. 【XJTU】数学建模

热门文章

  1. Cell发文!施一公科研团队取得重大突破
  2. 微信新功能又来了,这些功能再次打开了我新世界的大门!
  3. 女生的拳头有多厉害?
  4. 如何用数学方法估算一个女生前男友的数量?
  5. 批作业是小学老师的一大乐趣 | 今日最佳
  6. 43秒处竟惊现刘强东!印度动作大片《WAR》终极预告曝光
  7. 100个微信小程序的源码公开分享
  8. Boosting集合算法详解(一)
  9. rocketmq 顺序消费_10 分钟看懂消息队列 RocketMQ
  10. doxygen如何生成JAVA文档_有用Doxygen生成文档的吗?发一篇Doxygen的使用文档给大家,从网上搜来的。...