后缀数组

poj 1743

poj 3415

poj 2758

线段树

poj 2828

 每个人依次插队, pos表示这个人会差到第pos个人的右边, 树状数组维护,开始的时候全置1,表示每个位置都有一个人,就是最终的状态,然后按照时间顺序 倒序处理.  先处理最后一个人, 二分出前n项和等于其pos+1的位置, 那么这个人就会在这个位置,  对于最后一个人, 他恰好在 pos位置, 然后最后一个人的位置确定了,  树状数组改位置清零, 状态就是除去这个人的状态, 然后处理倒数第二个人, 以此类推. 线段树有个比较巧妙的写法,3年前的工作了, 也贴一下吧. 虽然测试没快多少, 但是树状数组n*logn*logn,因为有二分, 线段树只有nlogn. 线段树结点存区间的和, 查询一个值时, 左儿子和如果足够,就走左边, 否则减去左边的和,剩余部分走右边,返回走到叶子结点的id.

array

 1 //#define txtout
 2 //#define debug
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<stack>
13 #include<queue>
14 #include<set>
15 #include<map>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double pi=acos(-1.0);
20 const double eps=1e-8;
21 const int inf=0x3f3f3f3f;
22 const int M=2e5+10;
23 class One_Tree_Array { ///一维树状数组
24     static const int M=2e5+10; ///点的个数
25     typedef int typev;
26     typev a[M];
27     int n;
28 public:
29     void init(int tn) { ///传入点数,点下标 1 开始
30         n=tn;
31         for(int i=0; i<=n; i++) a[i]=0;
32     }
33     int lowb(int t) {
34         return t&(-t);
35     }
36     void add(int i,typev v) {
37         for(; i<=n; a[i]+=v,i+=lowb(i));
38     }
39     typev sum(int i) {
40         typev s=0;
41         for(; i>0; s+=a[i],i-=lowb(i));
42         return s;
43     }
44 } tree;
45 int n;
46 struct Q {
47     int pos,val;
48 } p[M];
49 int answer[M];
50 int Binary(int x){
51     int L=0,R=n-1,result=0;
52     while(L<=R){
53         int mid=(L+R)>>1;
54         if(tree.sum(mid+1)>=x){
55             result=mid;
56             R=mid-1;
57         }
58         else{
59             L=mid+1;
60         }
61     }
62     return result;
63 }
64 void solve() {
65     tree.init(n);
66     for(int i=1;i<=n;i++){
67         tree.add(i,1);
68     }
69     for(int i=n-1;i>=0;i--){
70         int to=Binary(p[i].pos+1);
71         answer[to]=p[i].val;
72         tree.add(to+1,-1);
73     }
74 }
75 int main() {
76 #ifdef txtout
77     freopen("in.txt","r",stdin);
78     freopen("out.txt","w",stdout);
79 #endif // txtout
80     while(~scanf("%d",&n)) {
81         for(int i=0; i<n; i++) {
82             scanf("%d%d",&p[i].pos,&p[i].val);
83         }
84         solve();
85         for(int i=0; i<n; i++) {
86             if(i) putchar(' ');
87             printf("%d",answer[i]);
88         }
89         puts("");
90     }
91     return 0;
92 }
View Code

相关文章:

  • 2021-05-30
  • 2021-11-14
  • 2021-09-17
  • 2021-06-29
  • 2021-06-30
  • 2021-09-13
  • 2021-05-23
  • 2021-11-12
猜你喜欢
  • 2021-09-11
  • 2021-11-29
  • 2022-12-23
  • 2021-05-25
  • 2021-06-27
  • 2021-11-14
相关资源
相似解决方案