【分块】 HDU 4638 Group
题意:区间[L, R] 之间排序后有多少段连续的数
思路:一个一个的向里面添加,只需要判断a[i]-1 和 a[i]+1是否已经添加在内,如果两个都在,则总段数减1,如果两个都不在,总段数加1,其他情况总段数不变
代码:
分块、
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; #define N 100100 bool vis[N]; int a[N], n, m, all, L, R, ans[N]; struct node { int l, r, b, id; bool operator<(const node &x)const{ if (b == x.b) return r < x.r; return b < x.b; } } q[N]; void query(int x, int y, int flag) { if (flag != 0) { for (int i=x; i<L; i++) { vis[a[i]] = true; if (vis[a[i]-1] && vis[a[i]+1]) all--; else if (!vis[a[i]-1] && !vis[a[i]+1]) all++; } for (int i=R+1; i<=y; i++) { vis[a[i]] = true; if (vis[a[i]-1] && vis[a[i]+1]) all--; else if (!vis[a[i]-1] && !vis[a[i]+1]) all++; } for (int i=L; i<x; i++) { vis[a[i]] = false; if (vis[a[i]-1] && vis[a[i]+1]) all++; else if (!vis[a[i]-1] && !vis[a[i]+1]) all--; } for (int i=y+1; i<=R; i++) { vis[a[i]] = false; if (vis[a[i]-1] && vis[a[i]+1]) all++; else if (!vis[a[i]-1] && !vis[a[i]+1]) all--; } } else { all = 0; for (int i=x; i<=y; i++) { vis[a[i]] = true; if (vis[a[i]-1] && vis[a[i]+1]) all--; else if (!vis[a[i]-1] && !vis[a[i]+1]) all++; } } L = x, R = y; } int main() { int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); int block_size = sqrt(n); for (int i=1; i<=n; i++) scanf("%d", &a[i]); for (int i=0; i<m; i++) { scanf("%d%d", &q[i].l, &q[i].r); q[i].b = q[i].l / block_size; q[i].id = i; } sort(q, q+m); memset(vis, false, sizeof(vis)); for (int i=0; i<m; i++) { query(q[i].l, q[i].r, i); ans[q[i].id] = all; } for (int i=0; i<m; i++) printf("%d\n", ans[i]); } return 0; }
树状数组、
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,r,n) for(int i=r;i<=n;i++) #define RREP(i,n,r) for(int i=n;i>=r;i--) const int MAXN=1e5+100; int tree[MAXN]; int n; int lowbit(int x) { return x&(-x); } void add(int pos,int val) { while(pos <=n) { tree[pos] += val; pos += lowbit(pos); } } int read(int x) { int s=0; while(x>0) { s += tree[x]; x -= lowbit(x);//x-lowbit(x)可以理解成变成了x的兄弟 } return s; } int A[MAXN],pos[MAXN]; struct node{ int l,r,index; bool operator <(const node& rsh)const{ if(r==rsh.r) return l<rsh.l; else return r<rsh.r; } }; vector<node> Q; int ans[MAXN]; int main() { int T; scanf("%d",&T); while(T--) { int m; scanf("%d%d",&n,&m); REP(i,1,n){ scanf("%d",&A[i]); pos[A[i]]=i; } Q.clear(); node tmp; REP(i,1,m) { scanf("%d%d",&tmp.l,&tmp.r); tmp.index=i; Q.push_back(tmp); } sort(Q.begin(),Q.end()); CL(tree,0); int j=0; for(int i=1;i<=n;i++) { add(i,1); if(A[i]+1<=n&&pos[A[i]+1]<i) { add(pos[A[i]+1],-1); } if(A[i]-1>=1&&pos[A[i]-1]<i) { add(pos[A[i]-1],-1); } while(Q[j].r==i) { ans[Q[j].index]=read(Q[j].r)-read(Q[j].l-1); j++; } } REP(i,1,m) { printf("%d\n",ans[i]); } } return 0; }