线段树

 

"Ray, Pass me the dishes!"

 UVALive - 3938 

题意:查询区间[x,y]之间的最大连续和的区间[a,b],输出a和b。

出了点差错,,晚上回去再做

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 
 6 const int maxn=500010;
 7 int max_sub[maxn<<2],max_pre[maxn<<2],max_suf[maxn<<2];
 8 int a;
 9 int n,m;
10 
11 void pushup(int rt){
12     max_sub[rt]=max(max(max_sub[rt<<1],max_sub[rt<<1|1]),max_suf[rt<<1]+max_pre[rt<<1|1]);
13     max_pre[rt]=max(max(max_pre[rt<<1],max_sub[rt<<1]+max_suf[rt<<1|1]),max_sub[rt<<1]+max_sub[rt<<1|1]);
14     max_suf[rt]=max(max(max_suf[rt<<1|1],max_suf[rt<<1]+max_sub[rt<<1|1]),max_sub[rt<<1]+max_sub[rt<<1|1]);
15 }
16 void build(int l,int r,int rt){
17     if(l==r){
18         scanf("%d",&a);
19         max_sum[rt]=max_pre[rt]=max_suf[rt]=a;
20         return ;
21     }
22     int m=l+(r-l)>>1;
23     build(lson);
24     build(rson);
25     pushup(rt);
26 }
27 void query(int L,int R,int l,int r,int rt){
28     int x,y;
29     if(L<=l&&r<=R){
30         
31     }
32     int m=l+(r-l)>>1;
33     if(L<=m){
34         
35     } 
36     if(R>m){
37         
38     }
39 }
40 int main(){
41     int kase=0;
42     while(scnaf("%d%d",&n,&m)!=EOF){
43         build(1,n,1);
44         int L,R;
45         printf("Case %d:\n",++kase);
46         while(m--){
47             scanf("%d%d",&L,&R);
48             query(L,R,1,n,1);
49         }
50     }
51     
52 }
View Code

 智商捉急

先贴上LRJ代码

  1 // LA3938 Ray, Pass me the dishes!
  2 // Rujia Liu
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 const int maxn = 500000 + 10;
  9 const int maxnode = 1000000 + 10;
 10 typedef long long LL;
 11 typedef pair<int,int> Interval;
 12 
 13 LL prefix_sum[maxn];
 14 
 15 LL sum(int L, int R) {
 16   return prefix_sum[R] - prefix_sum[L-1];
 17 }
 18 
 19 LL sum(Interval p) {
 20   return sum(p.first, p.second);
 21 }
 22 
 23 Interval better(Interval a, Interval b) {
 24   if(sum(a) != sum(b)) return sum(a) > sum(b) ? a : b;
 25   return a < b ? a : b; // 利用pair自带的字典序
 26 }
 27 
 28 int qL, qR;
 29 
 30 struct IntervalTree {
 31   int max_prefix[maxnode];
 32   int max_suffix[maxnode];
 33   Interval max_sub[maxnode];
 34 
 35   void build(int o, int L, int R) {
 36     if(L == R) {
 37       max_prefix[o] = max_suffix[o] = L;
 38       max_sub[o] = make_pair(L, L);
 39     } else {
 40       int M = L + (R-L)/2;
 41       // 递归创建子树
 42       int lc = o*2, rc = o*2+1;
 43       build(lc, L, M);
 44       build(rc, M+1, R);
 45 
 46       // 递推max_prefix
 47       LL v1 = sum(L, max_prefix[lc]);
 48       LL v2 = sum(L, max_prefix[rc]);
 49       if(v1 == v2) max_prefix[o] = min(max_prefix[lc], max_prefix[rc]);
 50       else max_prefix[o] = v1 > v2 ? max_prefix[lc] : max_prefix[rc];
 51 
 52       // 递推max_suffix
 53       v1 = sum(max_suffix[lc], R);
 54       v2 = sum(max_suffix[rc], R);
 55       if(v1 == v2) max_suffix[o] = min(max_suffix[lc], max_suffix[rc]);
 56       else max_suffix[o] = v1 > v2 ? max_suffix[lc] : max_suffix[rc];
 57 
 58       // 递推max_sub      
 59       max_sub[o] = better(max_sub[lc], max_sub[rc]); // 完全在左子树或者右子树
 60       max_sub[o] = better(max_sub[o], make_pair(max_suffix[lc], max_prefix[rc])); // 跨越中线
 61     }
 62   }
 63 
 64   Interval query_prefix(int o, int L, int R) {
 65     if(max_prefix[o] <= qR) return make_pair(L, max_prefix[o]);
 66     int M = L + (R-L)/2;
 67     int lc = o*2, rc = o*2+1;
 68     if(qR <= M) return query_prefix(lc, L, M);
 69     Interval i = query_prefix(rc, M+1, R);
 70     i.first = L;
 71     return better(i, make_pair(L, max_prefix[lc]));
 72   }
 73 
 74   Interval query_suffix(int o, int L, int R) {
 75     if(max_suffix[o] >= qL) return make_pair(max_suffix[o], R);
 76     int M = L + (R-L)/2;
 77     int lc = o*2, rc = o*2+1;
 78     if(qL > M) return query_suffix(rc, M+1, R);
 79     Interval i = query_suffix(lc, L, M);
 80     i.second = R;
 81     return better(i, make_pair(max_suffix[rc], R));
 82   }
 83 
 84   Interval query(int o, int L, int R) {
 85     if(qL <= L && R <= qR) return max_sub[o];
 86     int M = L + (R-L)/2;
 87     int lc = o*2, rc = o*2+1;
 88     if(qR <= M) return query(lc, L, M);
 89     if(qL > M) return query(rc, M+1, R);
 90     Interval i1 = query_prefix(rc, M+1, R); // 右半的前缀
 91     Interval i2 = query_suffix(lc, L, M); // 左半的后缀
 92     Interval i3 = better(query(lc, L, M), query(rc, M+1, R));
 93     return better(make_pair(i2.first, i1.second), i3);
 94   }
 95 };
 96 
 97 IntervalTree tree;
 98 
 99 int main() {
100   int kase = 0, n, a, Q;
101   while(scanf("%d%d", &n, &Q) == 2) {
102     prefix_sum[0] = 0;
103     for(int i = 0; i < n; i++) {
104       scanf("%d", &a);
105       prefix_sum[i+1] = prefix_sum[i] + a;
106     }
107     tree.build(1, 1, n);
108     printf("Case %d:\n", ++kase);
109     while(Q--) {
110       int L, R;
111       scanf("%d%d", &L, &R);
112       qL = L; qR = R;
113       Interval ans = tree.query(1, 1, n);
114       printf("%d %d\n", ans.first, ans.second);
115     }
116   }
117   return 0;
118 }
LRJ

 终于做出来了(其实是修改的某dalao的代码=_=||)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define lson l,m,rt<<1
 5 #define rson m+1,r,rt<<1|1
 6 #define CLR(m,a) memset(m,a,sizeof(m))
 7 #define ll long long
 8 const int maxn=500010;
 9 struct Node{
10     int x,y;
11     int pre,suf;
12 }node[maxn<<2];
13 int n,m;
14 ll s[maxn];
15 void pushup(int l,int r,Node &rt,Node ls,Node rs){
16     //pre
17     if(s[ls.pre]-s[l-1]>=s[rs.pre]-s[l-1]){
18         rt.pre=ls.pre;
19     }else{
20         rt.pre=rs.pre;
21     }
22     //suf
23     if(s[r]-s[ls.suf-1]>=s[r]-s[rs.suf-1]){
24         rt.suf=ls.suf;
25     }else{
26         rt.suf=rs.suf;
27     }
28     //x&&y
29     ll s1=s[ls.y]-s[ls.x-1];
30     ll s2=s[rs.y]-s[rs.x-1];
31     ll s3=s[rs.pre]-s[ls.suf-1];
32     if(s1>=s2){
33         rt.x=ls.x;rt.y=ls.y;
34     }else{
35         rt.x=rs.x;rt.y=rs.y;
36     }
37     if(s3==s[rt.y]-s[rt.x-1]){
38         if(ls.suf<rt.x){
39             rt.x=ls.suf;
40             rt.y=rs.pre;
41         }else if(ls.suf==rt.x&&rs.pre<rt.y){
42             rt.y=rs.pre;
43         }
44     }
45     if(s3>s[rt.y]-s[rt.x-1]){
46         rt.x=ls.suf;
47         rt.y=rs.pre;
48     }
49 }
50 void build(int l,int r,int rt){
51     if(l==r){
52         node[rt].x=node[rt].y=node[rt].pre=node[rt].suf=l;
53         return;
54     }
55     int m=l+(r-l)/2;
56     build(lson);
57     build(rson);
58     pushup(l,r,node[rt],node[rt<<1],node[rt<<1|1]);
59 }
60 Node query(int L,int R,int l,int r,int rt){
61     if(L<=l&&r<=R) return node[rt];
62     int m=l+(r-l)/2;
63     if(R<=m) return query(L,R,lson);
64     if(L>m) return query(L,R,rson);
65     Node a=query(L,R,lson);
66     Node b=query(L,R,rson);
67     Node c;
68     pushup(L,R,c,a,b);
69     return c;
70 }
71 int main(){
72     int kase=0;
73     while(scanf("%d%d",&n,&m)!=EOF){
74         s[0]=0;
75         int x;
76         for(int i=1;i<=n;i++){
77             scanf("%d",&x);
78             s[i]=s[i-1]+x;
79         }
80         build(1,n,1);
81         int L,R;
82         printf("Case %d:\n",++kase);
83         while(m--){
84             scanf("%d%d",&L,&R);
85             Node ans=query(L,R,1,n,1);
86             printf("%d %d\n",ans.x,ans.y);
87         }
88     }
89     return 0;
90 }
View Code

 

更为复杂的买卖房屋姿势

 HihoCoder - 1080

题意:两种操作,一是把区间[x,y]的房价加a,二是把区间[x,y[的房价设定为a。每次操作后输出全部房价的和。

增加用add标记,设定用set标记,需要注意的是pushdown时要先处理set标记。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 const int maxn=100010;
 6 struct Node{
 7     int sum;
 8     int set,add;
 9 }node[maxn<<2];
10   int n,m;
11 void pushup(int rt){
12     node[rt].sum=node[rt<<1].sum+node[rt<<1|1].sum;
13 }
14 
15 void build(int l,int r,int rt){
16     node[rt].add=node[rt].set=0;
17     if(l==r){
18         scanf("%d",&node[rt].sum);
19         return ;
20     }
21     int m=l+(r-l>>1);
22     build(lson);
23     build(rson);
24     pushup(rt);
25 }
26 void pushdown(int rt,int lg){
27     if(node[rt].set){
28         node[rt<<1].add=node[rt<<1|1].add=0;
29         node[rt<<1].set=node[rt<<1|1].set=node[rt].set;
30         node[rt<<1].sum=node[rt].set*(lg-(lg>>1));
31         node[rt<<1|1].sum=node[rt].set*(lg>>1);
32         node[rt].set=0;
33     }
34     if(node[rt].add){
35         node[rt<<1].add+=node[rt].add;
36         node[rt<<1|1].add+=node[rt].add;
37         node[rt<<1].sum+=node[rt].add*(lg-(lg>>1));
38         node[rt<<1|1].sum+=node[rt].add*(lg>>1);
39         node[rt].add=0;
40     }
41 }
42 
43 void update(int id,int L,int R,int c,int l,int r,int rt){
44     pushdown(rt,r-l+1);
45     if(L<=l&&r<=R){
46         if(id){
47             node[rt].set=c;
48             node[rt].sum=c*(r-l+1);
49         }else{
50             node[rt].add+=c;
51             node[rt].sum+=c*(r-l+1);
52         }
53         return ;
54     }
55     int m=l+(r-l>>1);
56     if(L<=m) update(id,L,R,c,lson);
57     if(R>m) update(id,L,R,c,rson);
58     pushup(rt);
59 }
60 
61 
62 int main(){
63 
64     scanf("%d%d",&n,&m);
65     n++;
66     build(1,n,1);
67     int id,L,R,c;
68     while(m--){
69         scanf("%d%d%d%d",&id,&L,&R,&c);
70         update(id,L+1,R+1,c,1,n,1);
71         printf("%d\n",node[1].sum);
72     }
73     return 0;
74 }
View Code

 进化版~更好理解一些。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 const int maxn=100010;
 6 struct Node{
 7     int sum;
 8     int set,add;
 9 }node[maxn<<2];
10 int n,m;
11 void pushup(int rt){
12     node[rt].sum=node[rt<<1].sum+node[rt<<1|1].sum;
13 }
14 
15 void build(int l,int r,int rt){
16     node[rt].add=node[rt].set=0;
17     if(l==r){
18         scanf("%d",&node[rt].sum);
19         return ;
20     }
21     int m=l+(r-l>>1);
22     build(lson);
23     build(rson);
24     pushup(rt);
25 }
26 void pushdown(int rt,int lg){
27     if(node[rt].set){
28         node[rt<<1].add=node[rt<<1|1].add=0;
29         node[rt<<1].set=node[rt<<1|1].set=node[rt].set;
30         node[rt<<1].sum=node[rt].set*(lg-(lg>>1));
31         node[rt<<1|1].sum=node[rt].set*(lg>>1);
32         node[rt].set=0;
33     }
34     if(node[rt].add){
35         node[rt<<1].add+=node[rt].add;
36         node[rt<<1|1].add+=node[rt].add;
37         node[rt<<1].sum+=node[rt].add*(lg-(lg>>1));
38         node[rt<<1|1].sum+=node[rt].add*(lg>>1);
39         node[rt].add=0;
40     }
41 }
42 
43 void update(int id,int L,int R,int c,int l,int r,int rt){
44     if(L<=l&&r<=R){
45         if(id){
46             node[rt].set=c;
47             node[rt].add=0;
48             node[rt].sum=c*(r-l+1);
49         }else{
50             node[rt].add+=c;
51             node[rt].sum+=c*(r-l+1);
52         }
53         return ;
54     }
55     pushdown(rt,r-l+1);
56     int m=l+(r-l>>1);
57     if(L<=m) update(id,L,R,c,lson);
58     if(R>m) update(id,L,R,c,rson);
59     pushup(rt);
60 }
61 
62 
63 int main(){
64     scanf("%d%d",&n,&m);
65     n++;
66     build(1,n,1);
67     int id,L,R,c;
68     while(m--){
69         scanf("%d%d%d%d",&id,&L,&R,&c);
70         update(id,L+1,R+1,c,1,n,1);
71         printf("%d\n",node[1].sum);
72     }
73     return 0;
74 }
先处理set_
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 const int maxn=100010;
 6 struct Node{
 7     int sum;
 8     int set,add;
 9 }node[maxn<<2];
10 int n,m;
11 void pushup(int rt){
12     node[rt].sum=node[rt<<1].sum+node[rt<<1|1].sum;
13 }
14 
15 void build(int l,int r,int rt){
16     node[rt].add=node[rt].set=0;
17     if(l==r){
18         scanf("%d",&node[rt].sum);
19         return ;
20     }
21     int m=l+(r-l>>1);
22     build(lson);
23     build(rson);
24     pushup(rt);
25 }
26 void pushdown(int rt,int lg){
27     if(node[rt].add){
28         if(node[rt].set) node[rt].set+=node[rt].add;   //!!!
29         node[rt<<1].add+=node[rt].add;
30         node[rt<<1|1].add+=node[rt].add;
31         node[rt<<1].sum+=node[rt].add*(lg-(lg>>1));
32         node[rt<<1|1].sum+=node[rt].add*(lg>>1);
33         node[rt].add=0;
34     }
35     if(node[rt].set){
36         node[rt<<1].add=node[rt<<1|1].add=0;
37         node[rt<<1].set=node[rt<<1|1].set=node[rt].set;
38         node[rt<<1].sum=node[rt].set*(lg-(lg>>1));
39         node[rt<<1|1].sum=node[rt].set*(lg>>1);
40         node[rt].set=0;
41     }
42 
43 }
44 
45 void update(int id,int L,int R,int c,int l,int r,int rt){
46     if(L<=l&&r<=R){
47         if(id){
48             node[rt].set=c;
49             node[rt].add=0;
50             node[rt].sum=c*(r-l+1);
51         }else{
52             node[rt].add+=c;
53             node[rt].sum+=c*(r-l+1);
54         }
55         return ;
56     }
57     pushdown(rt,r-l+1);
58     int m=l+(r-l>>1);
59     if(L<=m) update(id,L,R,c,lson);
60     if(R>m) update(id,L,R,c,rson);
61     pushup(rt);
62 }
63 
64 
65 int main(){
66     scanf("%d%d",&n,&m);
67     n++;
68     build(1,n,1);
69     int id,L,R,c;
70     while(m--){
71         scanf("%d%d%d%d",&id,&L,&R,&c);
72         update(id,L+1,R+1,c,1,n,1);
73         printf("%d\n",node[1].sum);
74     }
75     return 0;
76 }
先处理add_
(需要注意的是set可能也要被add_)

 

Beam Cannon

 HDU - 5091 

 很久之前做的,粘过来。。。

用到了离散化和扫描线,感觉综合度较高

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define lson l,m,rt<<1
 5 #define rson m+1,r,rt<<1|1
 6 const int maxn=40010;
 7 using namespace std;
 8 
 9 struct LINE
10 {
11     int x,y1,y2,v;
12     LINE(){}
13     LINE(int x,int y1,int y2,int v):
14         x(x),y1(y1),y2(y2),v(v){}
15     bool operator<(const LINE&a)const
16     {
17         return x<a.x||x==a.x&&v>a.v;  //优先处理入点
18     }
19 }line[maxn];
20 
21 int Y[maxn];//离散
22 int ct;
23 int n,w,h;
24 
25 int sum[maxn<<2],add[maxn<<2];
26 void pushup(int rt)
27 {
28     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
29 }
30 void build(int l,int r,int rt)
31 {
32     sum[rt]=add[rt]=0;
33     if(l==r) return ;
34     int m=(l+r)>>1;
35     build(lson);
36     build(rson);
37     pushup(rt);
38 }
39 void pushdown(int rt)
40 {
41     if(add[rt])
42     {
43         add[rt<<1]+=add[rt];
44         add[rt<<1|1]+=add[rt];
45         sum[rt<<1]+=add[rt];
46         sum[rt<<1|1]+=add[rt];
47         add[rt]=0;
48     }
49 }
50 void update(int L,int R,int v,int l,int r,int rt)
51 {
52     if(L<=l&&r<=R)
53     {
54         add[rt]+=v;
55         sum[rt]+=v;
56         return ;
57     }
58     pushdown(rt);
59     int m=(l+r)>>1;
60     if(L<=m) update(L,R,v,lson);
61     if(R>m) update(L,R,v,rson);
62     pushup(rt);
63 }
64 
65 int main()
66 {
67     while(scanf("%d",&n)&&n!=-1)
68     {
69         ct=0;
70         scanf("%d%d",&w,&h);
71         for(int i=0;i<n;i++)
72         {
73             int x,y;
74             scanf("%d%d",&x,&y);
75             x+=20001;
76             y+=20001;
77             Y[ct]=y;
78             line[ct++]=LINE(x,y,y+h,1);
79             Y[ct]=y+h;
80             line[ct++]=LINE(x+w,y,y+h,-1);
81         }
82         sort(Y,Y+ct);
83         sort(line,line+ct);
84         int num=unique(Y,Y+ct)-Y;
85         build(0,num-1,1);
86         int ans=0;
87         for(int i=0;i<ct;i++)
88         {
89             int l=lower_bound(Y,Y+num,line[i].y1)-Y;
90             int r=lower_bound(Y,Y+num,line[i].y2)-Y;
91             update(l,r,line[i].v,0,num-1,1);
92             ans=max(ans,sum[1]);
93         }
94         printf("%d\n",ans);
95     }
96 }
View Code

 

RMQ with Shifts

 UVA - 12299 

题意:将数组的某些数字循环移位,找区间最小值。

水题,又犯了sb错误=_=

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 
 6 const int maxn=100010;
 7 
 8 int minx[maxn<<4];
 9 int a[maxn];
10 int n,q;
11 void pushup(int rt){
12     minx[rt]=min(minx[rt<<1],minx[rt<<1|1]);
13 }
14 void build(int l,int r,int rt){
15     if(l==r){
16         minx[rt]=a[l];
17         return ;
18     }
19     int m=(l+r)>>1;
20     build(lson);
21     build(rson);
22     pushup(rt);
23 }
24 void update(int p,int x,int l,int r,int rt){
25     if(l==r){
26         minx[rt]=x;   //rt写成了l=_=||
27         return;
28     }
29     int m=(l+r)>>1;
30     if(p<=m) update(p,x,lson);
31     else update(p,x,rson);
32     pushup(rt);
33 }
34 int query(int L,int R,int l,int r,int rt){
35     if(L<=l&&r<=R){
36         return minx[rt];
37     }
38     int m=(l+r)>>1;
39     int ans=0x3f3f3f3f;
40     if(L<=m) ans=min(ans,query(L,R,lson));
41     if(R>m) ans=min(ans,query(L,R,rson));
42     return ans;
43 }
44 int b[20];
45 int main(){
46     while(scanf("%d%d",&n,&q)!=EOF){
47         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
48         getchar();  //换行符
49         build(1,n,1);
50         while(q--){
51             int cnt=0;
52             char c=getchar();
53             if(c=='q'){
54                 int L,R;
55                 while(c!='(') c=getchar();
56                 scanf("%d,%d)",&L,&R);
57                 getchar();  //换行符
58                 printf("%d\n",query(L,R,1,n,1));
59             }else{
60                 while(c!='(') c=getchar();
61                 while(c!=')') scanf("%d%c",&b[cnt++],&c);
62                 getchar();  //换行符
63                 
64                 int temp=a[b[0]];
65                 for(int i=0;i<cnt-1;i++){
66                     update(b[i],a[b[i+1]],1,n,1);
67                     a[b[i]]=a[b[i+1]];
68                 }
69                 update(b[cnt-1],temp,1,n,1);
70                 a[b[cnt-1]]=temp;
71             }
72         }
73     }
74     return 0;
75 }
View Code

 

SKYLINE

 UVALive - 4108 

题意:按顺序给出 n 个矩形,每给出一个矩形,统计它在多长的部分是最高的,并把这个长度称为该矩形的覆盖度,求最后总的覆盖度(每次得到的矩形的覆盖度之和)

线段树维护两个信息,即区间最小高度和最大高度。最小高度是指全部覆盖这个区间的高度,最大高度是这个区间任何一段被覆盖的高度。

最小高度往下传pushdown,最大高度pushup。

只有当查询区间的最小高度小于h时,才累加到结果(再次全部覆盖)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lson l,m,rt<<1
 4 #define rson m,r,rt<<1|1
 5 
 6 const int maxn=100010;
 7 
 8 int h[maxn<<2],overh[maxn<<2];
 9 int ans;
10 void pushup(int rt)
11 {
12     h[rt]=max(h[rt<<1],h[rt<<1|1]);
13 }
14 void pushdown(int rt){
15     overh[rt<<1]=max(overh[rt],overh[rt<<1]);
16     overh[rt<<1|1]=max(overh[rt],overh[rt<<1|1]);
17 }
18 void update(int L,int R,int c,int l,int r,int rt){
19     if(c<overh[rt]) return;
20     if(L<=l&&r<=R&&h[rt]<=c){
21         ans+=r-l;
22         h[rt]=c;
23         overh[rt]=c;
24         return ;
25     }
26     if(l==r-1) return ;
27     pushdown(rt);
28     int m=(l+r)>>1;
29     if(L<m) update(L,R,c,lson);
30     if(R>m) update(L,R,c,rson);
31     pushup(rt);
32 }
33 
34 int main(){
35     int t;
36     scanf("%d",&t);
37     while(t--){
38         ans=0;
39         memset(h,0,sizeof(h));
40         memset(overh,0,sizeof(overh));
41         int n;
42         int x,y,c;
43         scanf("%d",&n);
44         for(int i=0;i<n;i++){
45             scanf("%d%d%d",&x,&y,&c);
46             update(x,y,c,1,maxn,1);
47         }
48     printf("%d\n",ans);
49     }
50     return 0;
51 }
View Code

 

Permutation

 UVA - 11525 

 题意:求n个元素的第k个排列。k给出的形式要用到康拓展开。

学习了下康拓展开,题解连接

康托展开可以方便的求得1到n的排列任意一个排列在所有排列中的字典序排第几,逆康托展开可以求字典序第k大的排列是哪个。

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 const int maxn=50010;
 6 
 7 int sum[maxn<<2];
 8 
 9 void pushup(int rt){
10     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
11 }
12 
13 void build(int l,int r,int rt){
14     if(l==r){
15         sum[rt]=1;
16         return ;
17     }
18     int m=(l+r)>>1;
19     build(lson);
20     build(rson);
21     pushup(rt);
22 }
23 
24 int query(int ct,int l,int r,int rt){
25     if(l==r){
26         sum[rt]=0;
27         return l;
28     }
29     int m=(l+r)>>1;
30     int ans;
31     if(sum[rt<<1]>=ct) ans=query(ct,lson);
32     else ans=query(ct-sum[rt<<1],rson);
33     pushup(rt);
34     return ans;
35 }
36 
37 int main(){
38     int t;
39     int n,x;
40     scanf("%d",&t);
41     while(t--){
42         scanf("%d",&n);
43         int ct=n-1;
44         build(1,n,1);
45         scanf("%d",&x);
46         printf("%d",query(x+1,1,n,1));
47         while(ct--){
48             scanf("%d",&x);
49             printf(" %d",query(x+1,1,n,1));
50         }
51         puts("");
52     }
53     return 0;
54 }
View Code

 

 

 

 

 

 

posted @ 2017-07-31 14:33  yijiull  阅读(237)  评论(0编辑  收藏  举报