fzu 2059 并查集+离线处理
来源:互联网 发布:网站服务器和域名绑定 编辑:程序博客网 时间:2024/03/28 17:41
题意:
There is a array contain N(1<N<=100000) numbers. Now give you M(1<M<10000) query.
Every query will be:
1 x : ask longest substring which every number no less than x
2 y x : change the A[y] to x. there are at most change 10 times.
For each ask can you tell me the length of longest substring.
思路:
简单题,因为修改的次数很少。
对于确定的n个数字,可以先把n个数字从小到大排序,然后从大到小依次进行线段块的合并(如果一个点左右的线段块都已经访问过了,说明大小满足覆盖要求),这很适合并查集的特点,所以可以用并查集加个权值,来记录每一块的线段长度。
然后每一次修改之后,就重新进行上面过程。然后之后的每一个查询,都是二分查表即可。(这个地方我想是可以有O(1)的处理方式的)
code:
#include<cstdio>#include<iostream>#include<sstream>#include<cstring>#include<algorithm>#include<vector>#include<string>#include<queue>#include<map>#include<set>#include<cmath>#include<cctype>#include<cstdlib>using namespace std;#define INF 0x3f3f3f3f#define PI acos(-1.0)#define mem(a, b) memset(a, b, sizeof(a))#define mod 1000000007typedef pair<int,int> pii;typedef long long LL;//------------------------------const int maxn = 100005;const int maxm = 10005;int n,m;int x[maxm], a[maxn];struct node{ int num, id, ans; bool operator < (const node nt) const{ return num < nt.num; }}b[maxn];int p[maxn], len[maxn];int find(int x){ if(x == p[x]) return p[x]; else return p[x] = find(p[x]);}void union_(int u, int v){ int pu = find(u); int pv = find(v); if(pu != pv){ p[pu] = pv; len[pv] += len[pu]; }}void deal(){ for(int i = 1; i <= n; i++){ b[i].num = a[i]; b[i].id = i; } sort(b+1, b+1+n); int max_ = 0; memset(len, 0, sizeof(len)); for(int i = 1; i <= n; i++) p[i] = i; for(int i = n; i >= 1; i--){ int id = b[i].id; len[id] = 1; if(len[id-1]) union_(id-1, id); if(len[id+1]) union_(id+1, id); if(max_ < len[find(id)]) max_ = len[find(id)]; b[i].ans = max_; }// for(int i = 1; i <= n; i++){// printf("x = %d len = %d\n",b[i].num, b[i].ans);// }}int get_ans(int x){ node tmp; tmp.num = x; int id = lower_bound(b+1, b+1+n, tmp) - b;// printf("x = %d id = %d\n",x,id); return b[id].ans;}void solve(){ int op, a1, a2; deal(); for(int i = 1; i <= m; i++){ scanf("%d",&op); if(op == 2){ scanf("%d%d",&a1,&a2); a[a1] = a2; deal(); } if(op == 1){ scanf("%d",&a1); if(a1 > b[n].num){ printf("0\n"); continue; } int ans = get_ans(a1); printf("%d\n",ans); } }}int main(){ while(scanf("%d%d",&n,&m) != EOF){ for(int i = 1; i <= n; i++){ scanf("%d",&a[i]); } solve(); } return 0;}
0 0
- fzu 2059 并查集+离线处理
- 【FZU】Problem 2059 MM(离线处理并查集)
- hdu5441 离线处理+并查集
- HDU 5441 离线处理+并查集
- hdu 离线处理+并查集
- codeforces466E 并查集+离线处理+dfs
- hdu 5441 离线处理+并查集
- FZU -2233 (并查集)
- ZOJ 3261 Connections in GalaxyWar(并查集:离线处理)
- 【CodeForces】466E Information Graph 离线处理+并查集
- BZOJ-1015 StarWar星球大战 并查集+离线处理
- 【bzoj4320】【ShangHai2006 Homework】【并查集+离线处理】
- 4320: ShangHai2006 Homework 并查集+离线处理 思路题
- bzoj 1015: [JSOI2008]星球大战starwar 并查集+离线处理
- BZOJ1015: [JSOI2008]星球大战starwar 并查集 离线处理
- HDU 5441 Travel (离线处理+并查集)
- HDU 5441 Travel (并查集 离线处理)
- E. Envy(可撤销并查集+离线处理)
- 封装与继承
- 成功烧写tiny6410开发板
- HBase存储架构
- Dom4j解析,Sax解析,pull解析
- 设计模式(十九)状态模式(State)-行为型
- fzu 2059 并查集+离线处理
- jquery中的attr()方法
- 【笔试面试题】腾讯2013实习生面试算法题及参考答案
- PHP学习之路(一)——在zendstudio里用zendframework
- 五大常用算法之四:回溯法
- 第一个Spark程序
- 安卓的一些图片操作小计
- Learning C++ by Creating Games With UE4(15.05.11)-4(Chapter 8-3)Coding
- linux 之定时任务crontab