HDU 4630、BOJ 某题
来源:互联网 发布:淘宝客服招聘在家 编辑:程序博客网 时间:2024/06/05 12:46
两道离线线段树。
比赛时候没想到。。。。
扫描数组,i从1到n,线段树维护从1到i每一个约数(1~50000)的出现的最近位置,线段树存储的是约数的最大值
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;const int N=50050;struct Interval{ int l,r,id;}in[N];struct Tree{ int l,r,Max;}tree[N<<2];int n,m;int a[N];int pre[N];int ans[N];vector<int> factor[N];void init(){ for(int i=1;i<N;i++) for(int j=i;j<N;j+=i) factor[j].push_back(i);}bool cmp(struct Interval a,struct Interval b){ return a.r<b.r;}void build(int l,int r,int id){ tree[id].l=l; tree[id].r=r; tree[id].Max=0; if(l!=r){ int mid=(l+r)>>1; build(l,mid,id<<1); build(mid+1,r,id<<1|1); }}void update(int pos,int val,int id){ tree[id].Max=max(tree[id].Max,val); if(tree[id].l==tree[id].r) return ; int mid=(tree[id].l+tree[id].r)>>1; if(mid>=pos) update(pos,val,id<<1); else update(pos,val,id<<1|1);}int query(int l,int r,int id){ if(tree[id].l==l && tree[id].r==r) return tree[id].Max; int mid=(tree[id].l+tree[id].r)>>1; if(mid>=r) return query(l,r,id<<1); else if(mid<l) return query(l,r,id<<1|1); else return max(query(l,mid,id<<1),query(mid+1,r,id<<1|1));}int main(){ init(); int t,T; int i,j,k; scanf("%d",&T); for(t=1;t<=T;t++){ scanf("%d",&n); build(1,n,1); for(i=1;i<=n;i++){ scanf("%d",&a[i]); } scanf("%d",&m); for(i=0;i<m;i++){ scanf("%d %d",&in[i].l,&in[i].r); in[i].id=i; } sort(in,in+m,cmp); memset(pre,0,sizeof(pre)); for(i=1,j=0;i<=n && j<m;i++){ for(k=0;k<factor[a[i]].size();k++){ int tem=factor[a[i]][k]; if(pre[tem]!=0){ update(pre[tem],tem,1); } pre[tem]=i; } while(j<m && in[j].r==i){ ans[in[j].id]=query(in[j].l,in[j].r,1); j++; } } for(i=0;i<m;i++) printf("%d\n",ans[i]); } return 0;}
BOJ的那题找不到了,做完这道题之后,发现这两题很像,都是离线线段树做法。(这道题还是队友出的,膜拜)
先为数组中每个点i一个最小区间l,r满足a[i]>a[l] && a[i]<a[r],l<i<r
然后i从1开始扫描,每次把能加入的点加入,然后处理右端点为i的查询
#include<cstdio>#include<cstring>#include<algorithm>#include<stack>using namespace std;const int MAXN = 100000+5;const int INF = 0x3f3f3f3f;int T, N, Q, a[MAXN], s[MAXN], t[MAXN];int idq[MAXN], q[MAXN], cnt[MAXN], p[MAXN];int x[MAXN], y[MAXN], ida[MAXN];int Tr[MAXN<<2], mark[MAXN<<2];void Build(int idx, int L, int R){Tr[idx] = mark[idx] = 0;if (L == R)return;int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;Build(left, L, mid);Build(right, mid+1, R);}void PushDown(int idx){int left = idx<<1, right = idx<<1|1, &mk = mark[idx];Tr[left] += mk;mark[left] += mk;Tr[right] += mk;mark[right] += mk;mk = 0;}void Update(int idx, int L, int R, int l, int r, int c){if (l <= L && R <= r){Tr[idx] += c;mark[idx] += c;return;}if (mark[idx])PushDown(idx);int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;if (l <= mid)Update(left, L, mid, l, r, c);if (mid < r)Update(right, mid+1, R, l, r, c);}int Query(int idx, int L, int R, int x){if (x == L && R == x)return Tr[idx];if (mark[idx])PushDown(idx);int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;if (x <= mid)return Query(left, L, mid, x);elsereturn Query(right, mid+1, R, x);}bool cmpq(const int &a, const int &b){return t[a] < t[b];}bool cmpa(const int &a, const int &b){return y[a] < y[b];}int main(){//freopen("data.in", "r", stdin);//freopen("data.out", "w", stdout);scanf("%d", &T);for (int cas = 1; cas <= T; cas++){printf("Case %d:\n", cas);scanf("%d", &N);stack<int> stal, star;a[0] = 0;stal.push(0);for (int i = 1; i <= N; i++){scanf("%d", &a[i]);while (a[i] <= a[stal.top()])stal.pop();x[i] = stal.top();stal.push(i);}a[N+1] = INF;star.push(N+1);for (int i = N; i >= 1; i--){while (a[i] >= a[star.top()])star.pop();y[i] = star.top();star.push(i);ida[i] = i;}sort(ida+1, ida+1+N, cmpa);scanf("%d", &Q);for (int i = 1; i <= Q; i++){scanf("%d%d", &s[i], &t[i]);if (s[i] > t[i])swap(s[i], t[i]);idq[i] = i;q[i] = 0;}sort(idq+1, idq+1+Q, cmpq);Build(1, 1, N);for (int i = 1, j = 1, k = 1; i <= N; i++){for (; y[ida[k]] == i && k <= N; k++) if (x[ida[k]])Update(1, 1, N, 1, x[ida[k]], 1);for (; t[idq[j]] == i && j <= Q; j++)q[idq[j]] = Query(1, 1, N, s[idq[j]]);}for (int i = 1; i <= Q; i++)printf("%d\n", q[i]);}return 0;}
- HDU 4630、BOJ 某题
- POJ 1985 && BOJ 196 && HDU 2196
- BOJ 288
- BOJ 394
- BOJ 396
- BOJ 385
- BOJ 519
- BOJ 93
- BOJ 204
- BOJ 672
- BOJ 1454
- BOJ 387
- BOJ 652
- BOJ 1452
- BOJ 1461
- BOJ 1450
- Codeforces 163E && HDU 4117 && Noi2011阿狸的打字机 && boj 1602
- boj contest, C++
- LabVIEW动态数据交换DDE
- poj 3461 Oulipo(KMP,喜闻乐见纯模板)
- Java中static、this、super、final用法
- ETL 简介
- Android应用开发中对Bitmap的内存优化
- HDU 4630、BOJ 某题
- android中如何显示图片的一部分
- RUBY的CGI使用方法
- LabVIEW调用DDL中函数
- yield() sleep() wait() 区别
- netlink宏定义
- 项目开发经验----如何同时应对多个项目 & embedded tomcat 使用
- 使用strace跟踪系统调用
- 10161 - Ant on a Chessboard