"Ray, Pass me the dishes!"
题意:查询区间[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: ",++kase); 46 while(m--){ 47 scanf("%d%d",&L,&R); 48 query(L,R,1,n,1); 49 } 50 } 51 52 }
智商捉急
先贴上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: ", ++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 ", ans.first, ans.second); 115 } 116 } 117 return 0; 118 }
终于做出来了(其实是修改的某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: ",++kase); 83 while(m--){ 84 scanf("%d%d",&L,&R); 85 Node ans=query(L,R,1,n,1); 86 printf("%d %d ",ans.x,ans.y); 87 } 88 } 89 return 0; 90 }
更为复杂的买卖房屋姿势
题意:两种操作,一是把区间[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 ",node[1].sum); 72 } 73 return 0; 74 }
进化版~更好理解一些。
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 ",node[1].sum); 72 } 73 return 0; 74 }
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 ",node[1].sum); 74 } 75 return 0; 76 }
(需要注意的是set可能也要被add_)
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 ",ans); 95 } 96 }
RMQ with Shifts
题意:将数组的某些数字循环移位,找区间最小值。
水题,又犯了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 ",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 }
SKYLINE
题意:按顺序给出 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 ",ans); 49 } 50 return 0; 51 }
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 }