题意给了你N头牛,每头牛的强壮值是一个区间[s,e],如果第 i 头牛比第 j 头牛强壮那么必须满足 Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj;
为了满足这三个条件我们进行排序,先以e降序排为先决条件,若e相等则让s升序排列,如此即可满足三个条件,这道题目任意两头牛的强壮值区间有可能完全一样,这样就不需要重新用树状数组求一次和了,直接赋值即可,这样可以省很多时间,因为已经排序处理了,所以即便区间相等的 肯定就是相邻的,所以直接扫一遍即可,若不想等则用树状数组求和,往树状数组里添加的时候,以牛的s为序号,以1为value来加进去,这样处理以后就跟POJ2352简直是一模一样了
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #include<cctype> #define ll long long #define LL __int64 #define eps 1e-8 //const ll INF=9999999999999; #define inf 0xfffffff using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int> P; //vector<pair<int,int>> ::iterator iter; // //map<ll,int>mp; //map<ll,int>::iterator p; typedef struct Node { int s,e; int id; }; Node node[100000 + 5]; int n; int c[100000 + 5]; int ans[100000 + 5]; void clear() { memset(node,0,sizeof(node)); memset(c,0,sizeof(c)); memset(ans,0,sizeof(ans)); } bool cmp(Node x,Node y) { if(x.e == y.e) return x.s < y.s; return x.e > y.e; } int lowbit(int x) { return x&(-x); } void add(int i,int value) { while(i <= n) { c[i] += value; i += lowbit(i); } } int get_sum(int i) { int sum = 0; while(i > 0) { sum += c[i]; i -= lowbit(i); } return sum ; } int main() { while(scanf("%d",&n),n) { clear(); for(int i=1;i<=n;i++) { scanf("%d %d",&node[i].s,&node[i].e); node[i].s++; node[i].e++;//题目给的区间有从0开始 node[i].id = i; } sort(node + 1,node + n + 1,cmp); for(int i=1;i<=n;i++) { if(i > 1 && node[i].s == node[i-1].s && node[i].e == node[i-1].e)//相等直接诶赋值 ans[node[i].id] = ans[node[i-1].id]; else ans[node[i].id] = get_sum(node[i].s);//否则树状数组求和 add(node[i].s,1); } for(int i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; }
POJ2481 Cows 树状数组的简单应用,码迷,mamicode.com
时间: 2024-10-12 16:56:31