HDU 4638 Group(莫队)题解
题意:n个数,每个数有一个值,每次询问一个区间,问你这个区间能分成连续的几段(比如7 1 2 8 就是两端 1 2 和 7 8)
思路:莫队。因为L、R移动顺序wa了20发...问了一下别人,都是先扩大范围,再缩小...以后就这样写吧...
代码:
#include<cmath> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; const int maxn = 100000 + 10; int vis[maxn], arr[maxn], ans[maxn]; int T, n, m, ret; struct node{ int l, r; int pos, id; bool operator < (const node &x) const{ if(pos == x.pos) return r < x.r; return pos < x.pos; } }p[maxn]; void add(int x){ vis[x] = 1; if(vis[x - 1] && vis[x + 1]) ret--; else if(!vis[x - 1] && !vis[x + 1]) ret++; } void del(int x){ vis[x] = 0; if(vis[x - 1] && vis[x + 1]) ret++; else if(!vis[x - 1] && !vis[x + 1]) ret--; } void solve(){ memset(vis, 0 ,sizeof(vis)); int L = 1, R = 0; ret = 0; for(int i = 0; i < m; i++){ int l = p[i].l, r = p[i].r; if(r < L || l > R){ ret = 0; for(int i = L; i <= R; i++) vis[arr[i]] = 0; for(int i = l; i <= r; i++) add(arr[i]); L = l, R = r; } while(L > l){ L--; add(arr[L]); } while(R < r){ R++; add(arr[R]); } while(L < l){ del(arr[L]); L++; } while(R > r){ del(arr[R]); R--; } ans[p[i].id] = ret; } } int main(){ scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); int block = sqrt(n * 1.0); for(int i = 1; i <= n; i++) scanf("%d", &arr[i]); for(int i = 0; i < m; i++){ scanf("%d%d", &p[i].l, &p[i].r); p[i].id = i; p[i].pos = p[i].l / block; } sort(p, p + m); solve(); for(int i = 0; i < m; i++){ printf("%d\n", ans[i]); } } return 0; }
分类:
乱搞——莫队
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
· 程序员常用高效实用工具推荐,办公效率提升利器!