poj 2481 Cows(数状数组 或 线段树)
2015-10-12 18:24
246 查看
题意:对于两个区间,[si,ei] 和 [sj,ej],若 si <= sj and ei >= ej and ei - si > ej - sj 则说明区间 [si,ei] 比 [sj,ej] 强。对于每个区间,求出比它强的区间的个数。
解题思路:先将每个区间按 e 降序排列,在按 s 升序排列。则对于每个区间而言,比它强的区间的区间一定位于它的前面。 利用数状数组求每个区间[si,ei]前面 满足条件的区间[sj,ej]个数(条件:ej<=ei),再减去前面的和它相同的区间的个数。 也可以利用线段树,下面附上两种代码
代码:
解题思路:先将每个区间按 e 降序排列,在按 s 升序排列。则对于每个区间而言,比它强的区间的区间一定位于它的前面。 利用数状数组求每个区间[si,ei]前面 满足条件的区间[sj,ej]个数(条件:ej<=ei),再减去前面的和它相同的区间的个数。 也可以利用线段树,下面附上两种代码
代码:
数状数组 #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; int n,MAX,c[400010],r[400010],s[400010],e[400010]; int cmp(const int x,const int y){ if(e[x] > e[y]) return 1; else if( e[x] == e[y] ) return s[x] <= s[y]; return 0; } int lowbit(int x){ return x&(-x); } int sum(int x){ int ret = 0; while( x > 0){ ret += c[x]; x -= lowbit(x); } return ret; } void add(int x,int d){ while(x <= MAX){ c[x] += d; x += lowbit(x); } } int main(){ int i,j,ans[100010]; while(scanf("%d",&n) == 1 && n){ MAX = 0; for(i=0;i<n;i++){ scanf("%d%d",&s[i],&e[i]); s[i] ++; e[i] ++; MAX = MAX > s[i] ? MAX : s[i]; } for(i=0;i<n;i++) r[i] = i; sort(r,r+n,cmp); memset(c,0,sizeof(c)); for(i=0;i<n;i++){ int t = r[i]; ans[t] = sum(s[t]); add(s[t],1); for(j=i-1;j>=0;j--) if(e[r[j]] == e[t] && s[r[j]] == s[t]) ans[t] --; else break; } for(i=0;i<n-1;i++) printf("%d ",ans[i]); printf("%d\n",ans[n-1]); } return 0; } 线段树 #include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,MAX,r[200010],s[200010],e[200010]; struct node{ int l,r; int value; }a[800010]; int cmp(const int x,const int y){ if(e[x] > e[y]) return 1; else if(e[x] == e[y]) return s[x] <= s[y]; return 0; } void buildtree(int i,int l,int r){ a[i].l = l; a[i].r = r; a[i].value = 0; if( l== r) return ; int mid = (l+r) / 2 ; buildtree(i<<1,l,mid); buildtree((i<<1) + 1,mid+1,r); } int query(int i,int l,int r){ //a[i].value ++; if(a[i].l == l && a[i].r == r) return a[i].value ; // a[i].value ++; int mid = (a[i].l + a[i].r) / 2; if(r <= mid) return query(i<<1,l,r); else if(l > mid) return query((i<<1) + 1,l,r); return query(i<<1,l,mid) + query((i<<1) + 1,mid+1,r); } void update(int i,int num){ a[i].value++ ; if(a[i].l == a[i].r) return ; int mid = (a[i].l + a[i] .r) / 2; if(num <= mid) update(i<<1,num); else update((i<<1)+1,num); } int main(){ int i,j,ans[200010]; while(scanf("%d",&n) == 1 && n){ MAX = 0; for(i=1;i<=n;i++){ scanf("%d%d",&s[i],&e[i]); s[i] ++ ; e[i] ++ ; MAX = max(MAX,e[i]); } for(i=1;i<=n;i++) r[i] = i; sort(r+1,r+n+1,cmp); buildtree(1,1,MAX); for(i=1;i<=n;i++){ int t = r[i]; ans[t] = query(1,1,s[t]); update(1,s[t]); for(j=i-1;j>0;j--) if(s[r[j]] == s[t] && e[r[j]] == e[t]) ans[t] -- ; else break; } for(i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans ); } return 0; }
相关文章推荐
- Brackets sequence
- LinearLayout布局中如何让控件置底
- 对UIBackBarButtonItem的理解
- ReactJs 组件间通信
- php操作rabbitmq教程
- get_base(current->ldt[1])和get_base(current->ldt[2])
- android制,点击EditText时刻,隐藏系统软键盘,显示光标
- Python 获取新浪财经数据的案例
- Android中使用Gson解析数据
- tianchi微博预测-目前进度
- 数字(基础)
- Json解析
- android:在android studio中使用lambda,android lambda,retrolambda
- 腾讯Unity3D手游 dll加密分析
- Hive命令学习
- discuz论坛图片无法显示之图片流问题
- PHP引用问题
- [高中作文赏析]其实,生活中不乏精彩
- char nvarchar varchar
- jQuery锚点滚动js