文章标题 HDU 4638 : Group (莫队算法)
来源:互联网 发布:网络信息抓取 编辑:程序博客网 时间:2024/06/16 07:40
Group
题目链接
题意:有n个数的排列,然后有m个询问,然后对于连续的一段数,这些数可以作为一个分组,然后对于每次询问给定一个区间[ L,R ] ,问这个区间内有多少个组。
分析: 可以用莫队算法,对于当前已知区间[ L,R ] 的答案,我们可以O(1)去得到(L+1,R),(L-1,R),(L,R+1),(L,R-1)的答案,可以用对于当前的点 u, 如果加上他,如果flag[u-1],flag[u+1]已经在区间中,说明区间(答案)可以减1,如果flag[u-1]和flag[u+1]都没有被标记,说明加上他区间(答案)得加1,存在一个标记不改变答案;对于减去当前点 u ,则相反。
注意:就是有可能就是两个区间是不相交的,这个得特殊判断
代码:
#include<iostream>#include<string>#include<cstdio>#include<cstring>#include<vector>#include<math.h>#include<map>#include<queue> #include<algorithm>using namespace std;const int inf = 0x3f3f3f3f;typedef pair<int,int> pii;const int maxn=1e5+10;int R,L,ans;int res[maxn];struct node { int l,r,id;}p[maxn]; int pos[maxn];//表示在第几个块 bool cmp(node a,node b){//排序 if (pos[a.l]==pos[b.l])return pos[a.r]<pos[b.r]; return pos[a.l]<pos[b.l];}int a[maxn],n,m;int flag[maxn];void add(int x){//加入一个数 if (flag[a[x]])return; if (flag[a[x]-1]&&flag[a[x]+1])ans--;//区间减一 else if (flag[a[x]-1]==0&&flag[a[x]+1]==0)ans++;//区间加一 flag[a[x]]=1;//加上标记 }void del(int x){ if (flag[a[x]]==0)return; if (flag[a[x]-1]&&flag[a[x]+1])ans++;//区间加一 else if (flag[a[x]-1]==0&&flag[a[x]+1]==0)ans--;//区间减一 flag[a[x]]=0;//减去标记 }int main (){ int T; scanf ("%d",&T); while (T--){ scanf ("%d%d",&n,&m); memset (flag,0,sizeof (flag)); int block=sqrt(n); for (int i=1;i<=n;i++){ scanf ("%d",&a[i]); pos[i]=(i-1)/block+1;//得到快的位置 } for (int i=1;i<=m;i++){ scanf ("%d%d",&p[i].l,&p[i].r); p[i].id=i; } sort(p+1,p+1+m,cmp); L=1;R=0;ans=0; for (int i=1;i<=m;i++){ if (p[i].l>R||p[i].r<L){//区间不相交 while (L<=R){ flag[a[L++]]=0; } ans=0; L=p[i].l; R=p[i].l-1; while (R<p[i].r){ R++; add(R); } res[p[i].id]=ans; continue; } while (L<p[i].l){ del(L); L++; } while (L>p[i].l){ L--; add(L); } while (R<p[i].r){ R++; add(R); } while (R>p[i].r){ del(R); R--; } res[p[i].id]=ans; } for (int i=1;i<=m;i++){ printf ("%d\n",res[i]); } } return 0;}/*15 23 1 2 5 41 24 5*/
阅读全文
0 0
- 文章标题 HDU 4638 : Group (莫队算法)
- HDU 4638 Group(莫队算法)
- hdu 4638 Group(莫队算法)
- HDU 4638 Group 莫队算法
- HDU 4638 Group(莫队算法)
- hdu 4638 Group(莫队算法+分块)
- hdu 4638 Group (莫队算法 || 离线线段树)
- hdu 4638 Group(莫队算法|离线线段树)
- HDU 4638 Group (莫队算法||线段树离散查询)
- HDU 4638 Group 【树状数组,分块乱搞(莫队算法?)】
- 文章标题 HDU 2570 : 迷瘴(贪心)
- 文章标题 HDU 1969 : Pie(二分)
- 文章标题 HYSBZ 2038 : 小Z的袜子(hose) (莫队算法)
- 离线处理(线段树|树状数组)| 莫对算法 —— HDU 4638 Group
- 文章标题HDU 2141:Can you find it?(二分)
- 文章标题 HDU 3853:LOOPS (概率DP)
- 文章标题 HDU 5584:LCM Walk(数学推导)
- 文章标题 HDU 5272:Dylans loves numbers( 水)
- W10 jdk1.8环境变量配置
- 1056. 组合数的和(15)
- Java设计模式--桥接模式
- 最优贸易
- 火柴棒等式
- 文章标题 HDU 4638 : Group (莫队算法)
- C++类几种情况的内存布局
- Spring IOC 之注解配置、单元测试
- Nginx Lua 三种重定向的使用及比较
- Linux中unzip解压出现乱码,mismatching "local" filename和continuing with "central" filename version
- MySQL的Query Cache
- C语言中变量名及函数名的命名规则
- centos升级glibc(升级到 2.17版)
- 以前写的代码感觉很有用