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

    hdu1166,点修改,区间查询sum形式,最简单形式的线段树

     1 #include<cstdlib>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=50005;
    10 int sum[maxn<<2],a[maxn];
    11 void build(int rt,int l,int r){
    12     if(l==r){
    13         sum[rt]=a[l];
    14         return;
    15     }
    16     int mid=(l+r)>>1;
    17     build(rt<<1, l, mid);
    18     build(rt<<1|1, mid+1, r);
    19     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    20 }
    21 void update(int rt,int l,int r,int p,int c){
    22     if(l==r){
    23         sum[rt]+=c;
    24         return;
    25     }
    26     int mid=(l+r)>>1;
    27     if(p<=mid) update(rt<<1, l, mid, p, c);
    28     else update(rt<<1|1,mid+1,r, p, c);
    29     sum[rt]=sum[rt<<1|1]+sum[rt<<1];
    30 }
    31 int query(int rt,int l,int r,int tl,int tr){
    32     if(tl<=l&&tr>=r){
    33         return sum[rt];
    34     }
    35     int mid=(l+r)>>1,res=0;
    36     if(tl<=mid) res+=query(rt<<1, l, mid, tl, tr);
    37     if(tr>mid)  res+=query(rt<<1|1, mid+1, r, tl, tr);
    38     return res;
    39 }
    40 int main(){
    41     int t;
    42     cin>>t;
    43     for(int j=1;j<=t;j++){
    44         int n;
    45         cin>>n;
    46         for(int i=1;i<=n;i++) cin>>a[i];
    47         build(1, 1, n);
    48         cout<<"Case "<<j<<":
    ";
    49         string s;
    50         while(cin>>s){
    51             if(s[0]=='A'){
    52                 int a,b;
    53                 cin>>a>>b;
    54                 update(1, 1, n, a, b);
    55             }
    56             else if(s[0]=='S'){
    57                 int a,b;
    58                 cin>>a>>b;
    59                 update(1, 1, n, a, -b);
    60             }
    61             else if(s[0]=='Q'){
    62                 int a,b,ans;
    63                 cin>>a>>b;
    64                 ans=query(1, 1, n, a,b);
    65                 cout<<ans<<endl;
    66             }
    67             else{
    68                 break;
    69             }
    70         }
    71 
    72     }
    73 }
    View Code

    hdu1754 点修改,区间查询最大值形式

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=200005;
    10 int a[maxn],tree[maxn<<2];
    11 void pushup(int rt){
    12     tree[rt]=max(tree[rt<<1|1],tree[rt<<1]);
    13 }
    14 void build(int rt,int l,int r){
    15     if(l==r){
    16         tree[rt]=a[l];
    17         return;
    18     }
    19     int mid=(l+r)>>1;
    20     build(rt<<1,l,mid);
    21     build(rt<<1|1,mid+1,r);
    22     pushup(rt);
    23 }
    24 
    25 void update(int rt,int l,int r,int p,int c){
    26     if(l==r){
    27         tree[rt]=c;
    28         return;
    29     }
    30     int mid=(l+r)>>1;
    31     if(p<=mid) update(rt<<1, l, mid, p, c);
    32     else update(rt<<1|1, mid+1, r, p, c);
    33     pushup(rt);
    34 }
    35 
    36 int query(int rt,int l,int r,int tl,int tr){
    37     if(tl<=l&&tr>=r){
    38         return tree[rt];
    39     }
    40     int mid=(l+r)>>1,res=0;
    41     if(tl<=mid) res=max(res,query(rt<<1,l,mid,tl,tr));
    42     if(tr>mid) res=max(query(rt<<1|1,mid+1,r,tl,tr),res);
    43     return res;
    44 }
    45 
    46 int main(){
    47     int n,m;
    48     ios::sync_with_stdio(0);
    49     cin.tie(0);
    50     cout.tie(0);
    51     while(cin>>n>>m){
    52         memset(tree, 0, sizeof tree);
    53         memset(a,0,sizeof a);
    54         for(int i=1;i<=n;i++) cin>>a[i];
    55         build(1, 1, n);
    56         for(int i=0;i<m;i++){
    57             string s;
    58             cin>>s;
    59             if(s[0]=='Q'){
    60                 int a,b;
    61                 cin>>a>>b;
    62                 int ans=query(1, 1, n, a, b);
    63                 cout<<ans<<"
    ";
    64             }
    65             else if(s[0]=='U'){
    66                 int a,b;
    67                 cin>>a>>b;
    68                 update(1, 1, n, a, b);
    69             }
    70         }
    71     }
    72 
    73 }
    View Code

    poj3468  区间修改,区间求和,带lazy标记的线段树,会爆int

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=100005;
    10 ll a[maxn],sum[maxn<<2],add[maxn<<2];
    11 void pushup(ll rt){
    12     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    13 }
    14 void pushdown(ll rt,ll m){
    15     if(add[rt]){
    16         add[rt<<1]+=add[rt];
    17         add[rt<<1|1]+=add[rt];
    18         sum[rt<<1]+=(m-(m>>1))*add[rt];
    19         sum[rt<<1|1]+=(m>>1)*add[rt];
    20         add[rt]=0;
    21     }
    22 }
    23 void build(ll rt,ll l,ll r){
    24     add[rt]=0;
    25     if(l==r){
    26         sum[rt]=a[l];
    27         return;
    28     }
    29     ll mid=(l+r)>>1;
    30     build(rt<<1,l,mid);
    31     build(rt<<1|1,mid+1,r);
    32     pushup(rt);
    33 }
    34 
    35 
    36 void update(ll rt,ll l,ll r,ll tl,ll tr,ll c){
    37     if(tl<=l&&tr>=r){
    38         add[rt]+=c;
    39         sum[rt]+=c*(r-l+1);
    40         return;
    41     }
    42     pushdown(rt,r-l+1);
    43     ll mid=(l+r)>>1;
    44     if(tl<=mid) update(rt<<1, l, mid, tl, tr, c);
    45     if(tr>mid)  update(rt<<1|1, mid+1, r, tl, tr, c);
    46     pushup(rt);
    47 }
    48 
    49 
    50 ll query(ll rt,ll l,ll r,ll tl,ll tr){
    51     if(tl<=l&&tr>=r)    return sum[rt];
    52     pushdown(rt, r-l+1);
    53     ll mid=(l+r)>>1;
    54     ll res=0;
    55     if(tl<=mid) res+=query(rt<<1, l, mid, tl, tr);
    56     if(tr>mid) res+=query(rt<<1|1, mid+1, r,tl, tr);
    57     return res;
    58 }
    59 
    60 
    61 int main(){
    62     ll n,m;
    63     ios::sync_with_stdio(0);
    64     cin.tie(0);
    65     cout.tie(0);
    66     cin>>n>>m;
    67     for(int i=1;i<=n;i++) cin>>a[i];
    68     build(1, 1, n);
    69     for(int i=0;i<m;i++){
    70         string s;
    71         ll a,b,c;
    72         cin>>s;
    73         if(s[0]=='Q'){
    74             cin>>a>>b;
    75             ll ans=query(1, 1, n, a, b);
    76             cout<<ans<<endl;
    77         }
    78         else{
    79             cin>>a>>b>>c;
    80             update(1, 1, n, a, b, c);
    81         }
    82     }
    83     return 0;
    84 }
    View Code

    hdu1698 区间赋值,总区间求和

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=100005;
    10 int a[maxn],sum[maxn<<2],add[maxn<<2];
    11 
    12 void pushdown(int rt,int m){
    13     if(add[rt]){
    14         add[rt<<1]=add[rt];
    15         add[rt<<1|1]=add[rt];
    16         sum[rt<<1]=add[rt]*(m-(m>>1));
    17         sum[rt<<1|1]=add[rt]*(m>>1);
    18         add[rt]=0;
    19     }
    20 }
    21 
    22 void pushup(int rt){
    23     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    24 }
    25 
    26 void build(int rt,int l,int r){
    27     add[rt]=0;
    28     if(l==r){
    29         sum[rt]=1;
    30         return;
    31     }
    32     int mid=(l+r)>>1;
    33     build(rt<<1,l,mid);
    34     build(rt<<1|1, mid+1, r);
    35     pushup(rt);
    36 }
    37 
    38 void update(int rt,int l,int r,int tl,int tr,int c){
    39     if(tl<=l&&tr>=r){
    40         sum[rt]=c*(r-l+1);
    41         add[rt]=c;
    42         return;
    43     }
    44     pushdown(rt, r-l+1);
    45     int mid=(l+r)>>1;
    46     if(tl<=mid) update(rt<<1,l,mid,tl,tr, c);
    47     if(tr>mid)  update(rt<<1|1, mid+1, r, tl, tr, c);
    48     pushup(rt);
    49 }
    50 /*
    51 int query(int rt,int l,int r,int tl,int tr){
    52     if(tl<=l&&tr>=r){
    53         return sum[rt];
    54     }
    55     pushdown(rt,r-l+1);
    56     int mid=(l+r)>>1,res=0;
    57     if(l<=mid) res+=query(rt,l,mid,tl,tr);
    58     if(r>mid) res+=query(rt,mid+1,r,tl,tr);
    59     return res;
    60 }
    61 */
    62 int main(){
    63     ios::sync_with_stdio(0);
    64     cin.tie(0);
    65     cout.tie(0);
    66     int t;
    67     cin>>t;
    68     for(int i=1;i<=t;i++){
    69         int n,m;
    70         cin>>n>>m;
    71         build(1, 1, n);
    72         for(int j=0;j<m;j++){
    73             int a,b,c;
    74             cin>>a>>b>>c;
    75             update(1, 1, n, a, b, c);
    76         }
    77         cout<<"Case "<<i<<": The total value of the hook is ";
    78         cout<<sum[1]<<".
    ";
    79     }
    80 }
    View Code
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=100005;
    10 int a[maxn],sum[maxn<<2],add[maxn<<2];
    11 
    12 void pushdown(int rt,int m){
    13     if(add[rt]){
    14         add[rt<<1]=add[rt];
    15         add[rt<<1|1]=add[rt];
    16         sum[rt<<1]=add[rt]*(m-(m>>1));
    17         sum[rt<<1|1]=add[rt]*(m>>1);
    18         add[rt]=0;
    19     }
    20 }
    21 
    22 void pushup(int rt){
    23     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    24 }
    25 
    26 void build(int rt,int l,int r){
    27     add[rt]=0;
    28     if(l==r){
    29         sum[rt]=1;
    30         return;
    31     }
    32     int mid=(l+r)>>1;
    33     build(rt<<1,l,mid);
    34     build(rt<<1|1, mid+1, r);
    35     pushup(rt);
    36 }
    37 
    38 void update(int rt,int l,int r,int tl,int tr,int c){
    39     if(tl<=l&&tr>=r){
    40         sum[rt]=c*(r-l+1);
    41         add[rt]=c;
    42         return;
    43     }
    44     pushdown(rt, r-l+1);
    45     int mid=(l+r)>>1;
    46     if(tl<=mid) update(rt<<1,l,mid,tl,tr, c);
    47     if(tr>mid)  update(rt<<1|1, mid+1, r, tl, tr, c);
    48     pushup(rt);
    49 }
    50 
    51 int query(int rt,int l,int r,int tl,int tr){
    52     if(tl<=l&&tr>=r){
    53         return sum[rt];
    54     }
    55     pushdown(rt,r-l+1);
    56     int mid=(l+r)>>1,res=0;
    57     if(tl<=mid) res+=query(rt,l,mid,tl,tr);
    58     if(tr>mid) res+=query(rt,mid+1,r,tl,tr);
    59     return res;
    60 }
    61 
    62 int main(){
    63     ios::sync_with_stdio(0);
    64     cin.tie(0);
    65     cout.tie(0);
    66     int t;
    67     cin>>t;
    68     for(int i=1;i<=t;i++){
    69         int n,m;
    70         cin>>n>>m;
    71         build(1, 1, n);
    72         for(int j=0;j<m;j++){
    73             int a,b,c;
    74             cin>>a>>b>>c;
    75             update(1, 1, n, a, b, c);
    76         }
    77         cout<<"Case "<<i<<": The total value of the hook is ";
    78         cout<<query(1, 1, n, 1, 2)<<".
    ";
    79     }
    80 }
    View Code

    hdu4417 线段树离线处理,求任意区间>某数的个数

     1 #include<cstdlib>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=100005;
    10 int sum[maxn<<2];
    11 struct nod{
    12     int val;
    13     int id;
    14     bool operator<(const nod&a)const{
    15         return val<a.val;
    16     }
    17 }a[maxn];
    18 
    19 
    20 void build(int rt,int l,int r){
    21     if(l==r){
    22         sum[rt]=a[l].val;
    23         return;
    24     }
    25     int mid=(l+r)>>1;
    26     build(rt<<1, l, mid);
    27     build(rt<<1|1, mid+1, r);
    28     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    29 }
    30 
    31 
    32 void update(int rt,int l,int r,int p,int c){
    33     if(l==r){
    34         sum[rt]+=c;
    35         return;
    36     }
    37     int mid=(l+r)>>1;
    38     if(p<=mid) update(rt<<1, l, mid, p, c);
    39     else update(rt<<1|1,mid+1,r, p, c);
    40     sum[rt]=sum[rt<<1|1]+sum[rt<<1];
    41 }
    42 
    43 
    44 int query(int rt,int l,int r,int tl,int tr){
    45     if(tl<=l&&tr>=r){
    46         return sum[rt];
    47     }
    48     int mid=(l+r)>>1,res=0;
    49     if(tl<=mid) res+=query(rt<<1, l, mid, tl, tr);
    50     if(tr>mid)  res+=query(rt<<1|1, mid+1, r, tl, tr);
    51     return res;
    52 }
    53 
    54 
    55 struct node{
    56     int l,r,h,id;
    57 }q[100005];
    58 bool cmp1(node &a,node &b){
    59     return a.h<b.h;
    60 }
    61 bool cmp2(node &a,node &b){
    62     return a.id<b.id;
    63 }
    64 
    65 int ans[100005];
    66 int main(){
    67     int t;
    68     ios::sync_with_stdio(0);
    69     cin.tie(0);
    70     cout.tie(0);
    71     cin>>t;
    72     for(int k=1;k<=t;k++){
    73         int n,m;
    74         cin>>n>>m;
    75         for(int i=1;i<=n;i++) cin>>a[i].val,a[i].id=i;
    76         sort(a+1,a+n+1);
    77         memset(sum, 0, sizeof sum);
    78         for(int i=0;i<m;i++){
    79             cin>>q[i].l>>q[i].r>>q[i].h;
    80             q[i].id=i;
    81         }
    82         sort(q,q+m,cmp1);
    83         int tot=1;
    84         for(int i=0;i<m;i++){
    85             while(q[i].h>=a[tot].val&&tot<=n){
    86                 update(1, 1, n,a[tot].id, 1);
    87                 tot++;
    88             }
    89             ans[q[i].id]=query(1, 1, n, q[i].l+1, q[i].r+1);
    90         }
    91         sort(q,q+m,cmp2);
    92         cout<<"Case "<<k<<":
    ";
    93         for(int i=0;i<m;i++){
    94             cout<<ans[i]<<"
    ";
    95         }
    96     }
    97     return 0;
    98 }
    View Code

     hdu5692 dfs序+线段树,一定注意求和的时候不要乘区间长度,要符合题意。

      1 #pragma comment(linker, "/STACK:1024000000,1024000000") `
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<iostream>
      7 #include<cmath>
      8 #define inf 1e18
      9 typedef long long ll;
     10 using namespace std;
     11 const int maxn=1e5+4;
     12 ll head[maxn<<2],in[maxn<<2],out[maxn<<2],cnt,num;
     13 ll dis[maxn<<2],b[maxn<<2],va[maxn<<2];
     14 ll sum[maxn<<2],add[maxn<<2];
     15 ll n,m;
     16 struct Edge{
     17     ll to,net;//to表示终点,next表示下一条边
     18 }edge[maxn<<2];
     19 
     20 void add_edge(ll u,ll v){
     21     edge[cnt].net=head[u];
     22     edge[cnt].to=v;
     23     head[u]=cnt++;
     24 }
     25 
     26 void dfs(int u,int fa){
     27     num++;
     28     b[num]=dis[u];//?
     29     in[u]=num;
     30     for(ll i=head[u];i!=-1;i=edge[i].net){
     31         ll v=edge[i].to;
     32         if(v!=fa){
     33             dis[v]=dis[u]+va[v];
     34             dfs(v,u);
     35         }
     36     }
     37     out[u]=num;
     38 }
     39 
     40 
     41 
     42 void pushup(ll rt){
     43     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
     44 }
     45 
     46 void pushdown(ll rt,ll m){
     47     if(add[rt]){
     48         add[rt<<1]+=add[rt];
     49         add[rt<<1|1]+=add[rt];
     50         sum[rt<<1]+=add[rt];
     51         sum[rt<<1|1]+=add[rt];
     52         add[rt]=0;
     53     }
     54 }
     55 
     56 void build(ll rt,ll l,ll r){
     57     add[rt]=0;
     58     if(l==r){
     59         sum[rt]=b[l];
     60         return;
     61     }
     62     ll mid=(l+r)>>1;
     63     build(rt<<1,l,mid);
     64     build(rt<<1|1,mid+1,r);
     65     pushup(rt);
     66 }
     67 
     68 
     69 void update(ll rt,ll l,ll r,ll tl,ll tr,ll c){
     70     if(tl<=l&&tr>=r){
     71         add[rt]+=c;
     72         sum[rt]+=c;//一定注意这里,每条路径都加,而不是都加,一定注意题意
     73         return;
     74     }
     75     pushdown(rt,r-l+1);
     76     ll mid=(l+r)>>1;
     77     if(tl<=mid) update(rt<<1, l, mid, tl, tr, c);
     78     if(tr>mid)  update(rt<<1|1, mid+1, r, tl, tr, c);
     79     pushup(rt);
     80 }
     81 
     82 
     83 ll query(ll rt,ll l,ll r,ll tl,ll tr){
     84     if(tl<=l&&tr>=r)    return sum[rt];
     85     pushdown(rt, r-l+1);
     86     ll mid=(l+r)>>1;
     87     ll res=-inf;
     88     if(tl<=mid) res=max(res,query(rt<<1, l, mid, tl, tr));
     89     if(tr>mid) res=max(res,query(rt<<1|1, mid+1, r,tl, tr));
     90     return res;
     91 }
     92 
     93 
     94 int main(){
     95     ll t,c,bb,d;
     96     ios::sync_with_stdio(0);
     97     cin.tie(0);
     98     cout.tie(0);
     99     cin>>t;
    100     for(int k=1;k<=t;k++){
    101         memset(head, -1, sizeof head);
    102         memset(sum, 0, sizeof sum);
    103         memset(dis, 0, sizeof dis);
    104         cout<<"Case #"<<k<<":
    ";
    105         num=0;
    106         cnt=0;
    107         cin>>n>>m;
    108         for(int i=1;i<=n-1;i++){
    109             cin>>c>>bb;
    110             add_edge(c, bb);
    111             add_edge(bb, c);
    112         }
    113         for(int i=0;i<n;i++) cin>>va[i];
    114         dis[0]=va[0];
    115         dfs(0,-1);
    116         build(1, 1, num);
    117         for(int i=0;i<m;i++){
    118             cin>>bb;
    119             if(bb){
    120                 cin>>c;
    121                 ll ans=query(1, 1, num,in[c], out[c]);
    122                 cout<<ans<<"
    ";
    123             }
    124             else{
    125                 cin>>c>>d;
    126                 update(1, 1, num,in[c], out[c],d-va[c]);
    127                 va[c]=d;
    128             }
    129         }
    130         
    131     }
    132     return 0;
    133 }
    View Code

    待补

  • 相关阅读:
    20200929-git地址
    20200917-1 每周例行报告
    20200917-2 词频统计
    20200917-3 白名单
    20200910-1 每周例行报告
    20200910-2 博客作业
    20200924-3 单元测试,结对
    20200924-2 功能测试
    20200924-5 四则运算试题生成,结对
    20200924-4 代码规范,结对要求
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7300613.html
Copyright © 2011-2022 走看看