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 }
AC Code