MDeath-Kid

- M I T & Y
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

HUST1443

Posted on 2011-05-29 22:03  MDeath-Kid  阅读(180)  评论(0编辑  收藏  举报

没见有人贴出来,一个1040ms的代码贴着了。

大概思路就是:hash数组压缩+逆序数+树状数组求和+map-定位hash。

测试数据也挺强。

代码贴这:

1443
1 /*
2 m332463970 1443 Accepted 5320 kb 1040 ms C++ 2656 B 2011-05-29 21:49:31
3 */#include<stdio.h>
4 //#include<conio.h>
5 #include<iostream>
6 #include<string.h>
7 #include<math.h>
8 #include<vector>
9 #include<algorithm>
10 #include<set>
11 #include<map>
12 #include<stack>
13 #define MAXN 100005
14 using namespace std;
15 int a[MAXN],b[MAXN];
16 //求sum{[0..n-1]}
17 //维护和查询复杂度均为O(logn)
18 //用于动态求子段和,数组内容保存在sum.a[]中
19 //可以改成其他数据类型
20 #include <string.h>
21 #define lowbit(x) ((x)&((x)^((x)-1)))
22 typedef int elem_t;
23
24 struct sum{
25 elem_t a[MAXN],c[MAXN],ret;
26 int n;
27 void init(int i){memset(a,0,sizeof(a));memset(c,0,sizeof(c));n=i;}
28 void update(int i,elem_t v){for (v-=a[i],a[i++]+=v;i<=n;c[i-1]+=v,i+=lowbit(i));}
29 elem_t query(int i){for (ret=0;i;ret+=c[i-1],i^=lowbit(i));return ret;}
30 };
31 int main()
32 {
33 int n,m;
34 map<int,int> mpt;
35 map<int,int>::iterator p;
36 sum smpt;
37 while(scanf("%d%d",&n,&m)!=EOF)
38 {
39 mpt.clear();
40 memset(a,0,sizeof(a));
41 memset(b,0,sizeof(b));
42 smpt.init(n);
43 for(int i=0;i<n;i++)
44 {
45 scanf("%d",&a[i]);
46 }
47 sort(a,a+n);
48 int tmp=0,k=0;
49 b[k++]=1;mpt[a[0]]=0;
50 for(int i=0;i<n-1;i++)
51 {
52 tmp=a[i];
53 if(a[i+1]==tmp)
54 {
55 b[k-1]+=1;
56 }
57 else
58 {
59 mpt[a[i+1]]=k;
60 b[k++]=1;
61 }
62 }
63 for(int i=0;i<k;i++)
64 smpt.update(i,b[i]);
65 /*for(int i=0;i<n;i++)
66 {
67 printf("%d ",a[i]);
68 }
69 cout<<endl;
70 for(int i=0;i<n;i++)
71 {
72 printf("%d ",b[i]);
73 }
74 cout<<endl;
75 for(p=mpt.begin();p!=mpt.end();p++)
76 {
77 cout<<p->first<<"--"<<p->second<<endl;
78 }*/
79 int inta;
80 for(int i=0;i<m;i++)
81 {
82 int k;
83 scanf("%d",&inta);
84 if(inta>a[n-1])
85 {
86 printf("%d\n",n);
87 continue;
88 }
89 int siz1=mpt.size();
90 mpt[inta]++;
91 int siz2=mpt.size();
92 p=mpt.find(inta);
93 //cout<<p->first<<"--"<<p->second<<endl;
94 if(siz1!=siz2)
95 p++,k=p->second;
96 else
97 k=p->second-1;
98 //cout<<p->first<<"--"<<p->second<<endl;
99 //cout<<k<<endl;
100 printf("%d\n",smpt.query(k));
101 if(siz1!=siz2)
102 p--,mpt.erase(p);
103 else
104 mpt[inta]--;
105 }
106 }
107 }