http://acm.hfut.edu.cn/OnlineJudge/
个人感觉是挺有意思的一道题目,排序+离线处理+线段树统计。
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 #define maxn 20005 7 struct node{ 8 int lnum,rnum,num; 9 }setree[maxn<<2]; 10 struct op{ 11 int num,id; 12 }mes[maxn]; 13 struct opp{ 14 int q,id; 15 }cmd[maxn]; 16 int ans[maxn]; 17 bool cmp1(struct op a,struct op b) 18 { 19 return a.num>b.num; 20 } 21 bool cmp2(struct opp a,struct opp b) 22 { 23 return a.q>b.q; 24 } 25 void build(int l,int r,int rt) 26 { 27 setree[rt].lnum=-1; 28 setree[rt].rnum=-1; 29 setree[rt].num=0; 30 if(l==r) 31 return; 32 int m=(l+r)>>1; 33 build(lson); 34 build(rson); 35 } 36 void pushup(int rt) 37 { 38 setree[rt].lnum=setree[rt<<1].lnum; 39 setree[rt].rnum=setree[rt<<1|1].rnum; 40 setree[rt].num=setree[rt<<1].num+setree[rt<<1|1].num; 41 if(setree[rt<<1].rnum>0&&setree[rt<<1|1].lnum>0) 42 setree[rt].num--; 43 } 44 void update(int l,int r,int rt,int num,int c) 45 { 46 if(l==r){ 47 setree[rt].lnum=setree[rt].rnum=c; 48 setree[rt].num=1; 49 return; 50 } 51 int m=(l+r)>>1; 52 if(num<=m) 53 update(lson,num,c); 54 else 55 update(rson,num,c); 56 pushup(rt); 57 } 58 int main() 59 { 60 int n; 61 scanf("%d",&n); 62 for(int i=1;i<=n;i++){ 63 scanf("%d",&mes[i].num); 64 mes[i].id=i; 65 } 66 int m; 67 scanf("%d",&m); 68 for(int i=1;i<=m;i++){ 69 scanf("%d",&cmd[i].q); 70 cmd[i].id=i; 71 } 72 sort(mes+1,mes+n+1,cmp1); 73 sort(cmd+1,cmd+m+1,cmp2); 74 build(1,n,1); 75 int k=1; 76 for(int i=1;i<=m;i++){ 77 while(mes[k].num>cmd[i].q){ 78 update(1,n,1,mes[k].id,mes[k].num); 79 k++; 80 } 81 ans[cmd[i].id]=setree[1].num; 82 } 83 for(int i=1;i<=m;i++) 84 printf("%d\n",ans[i]); 85 return 0; 86 }