zoukankan      html  css  js  c++  java
  • 线段树

     

    "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:
    ",++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:
    ", ++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 }
    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:
    ",++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 }
    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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
  • 相关阅读:
    U3D shaderlab 相关指令开关
    CCF NOI1073
    CCF NOI1185
    CCF NOI1077(自然数的拆分问题 )
    CCF NOI1070(汉诺塔)
    CCF NOI1069
    2018年全国多校算法寒假训练营练习比赛(第一场)G.圆圈
    poj1941(递归)
    Codeforce914B (Conan and Agasa play a Card Game)
    Codeforce916B
  • 原文地址:https://www.cnblogs.com/yijiull/p/7262965.html
Copyright © 2011-2022 走看看