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

     1 //hdu 5726 
     2 //区间gcd
     3 #include <iostream>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <string>
     7 #include <algorithm>
     8 #include <utility>
     9 #include <vector>
    10 #include <map>
    11 #include <queue>
    12 #include <stack>
    13 #include <cstdlib>
    14 typedef long long ll;
    15 #define lowbit(x) (x&(-x))
    16 #define ls l,m,rt<<1
    17 #define rs m+1,r,rt<<1|1
    18 using namespace std;
    19 int t,n,q;
    20 const int N=1e5+9;
    21 int a[N],tree[N<<2];
    22 map<int,ll>dp[N],ans;
    23 void init()
    24 {
    25     for(int i=0;i<=n;i++)  dp[i].clear();
    26     ans.clear();//多组输入,要清空。
    27     for(int i=1;i<=n;i++)
    28     {
    29         dp[i][a[i]]++;
    30         ans[a[i]]++;
    31         for(auto it=dp[i-1].begin();it!=dp[i-1].end();it++){
    32             int p=it->first;
    33             ll q=it->second;
    34             int w=__gcd(a[i],p);
    35             dp[i][w]+=q;//包含第i个数的gcd为w的区间个数。
    36             ans[w]+=q;//gcd为w的区间个数    
    37         }
    38     }
    39 }
    40 void ph(int rt)
    41 {
    42     tree[rt]=__gcd(tree[rt<<1],tree[rt<<1|1]);
    43 }
    44 void build(int l=1,int r=n,int rt=1)
    45 {
    46     if(l==r)
    47     {
    48         tree[rt]=a[l];
    49         return ;
    50     }
    51     int  m=(r+l)>>1;
    52     build(ls);build(rs);
    53     ph(rt);
    54 }
    55 int  query(int l1,int r1,int l=1,int r=n,int rt=1)
    56 {
    57     if(l1<=l&&r1>=r) {
    58         return tree[rt];
    59     }
    60     int m=(r+l)>>1;
    61     if(l1>m) return   query(l1,r1,rs);//l1==m时左右都要查询。
    62     if(r1<=m)  return query(l1,r1,ls);
    63     return __gcd(query(l1,r1,ls),query(l1,r1,rs));
    64 }
    65 int main()
    66 {
    67     scanf("%d",&t);
    68     for(int i=1;i<=t;i++)
    69     {
    70         printf("Case #%d:
    ",i);
    71         scanf("%d",&n);
    72         for(int i=1;i<=n;i++)
    73         {
    74             scanf("%d",&a[i]);
    75         }
    76         init();
    77         build();
    78         scanf("%d",&q);
    79         int x,y;
    80         while(q--)
    81         {
    82             scanf("%d%d",&x,&y);
    83             int ret=query(x,y);
    84             printf("%d %lld
    ",ret,ans[ret]);
    85         }
    86     }
    87     return 0;
    88 }
    
    
    
    
    
     1 /hdu 1754
    // 单点更新,区间极值
    2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <utility> 8 #include <vector> 9 #include <map> 10 #include <queue> 11 #include <stack> 12 #include <cstdlib> 13 #include <cmath> 14 typedef long long ll; 15 #define lowbit(x) (x&(-x)) 16 #define ls l,m,rt<<1 17 #define rs m+1,r,rt<<1|1 18 using namespace std; 19 #define pi acos(-1) 20 const double e = 2.71828182845; 21 int n,m; 22 const int N=2e5+9; 23 int tree[N<<2],a[N]; 24 char s[2]; 25 void ph(int rt){ 26 tree[rt]=max(tree[rt<<1],tree[rt<<1|1]); 27 } 28 void build(int l=1,int r=n,int rt=1){ 29 if(l==r){ 30 tree[rt]=a[l]; 31 return ; 32 } 33 int m=(l+r)>>1; 34 build(ls);build(rs); 35 ph(rt); 36 } 37 int query(int l1,int r1,int l=1,int r=n,int rt=1){ 38 if(l1<=l&&r1>=r){ 39 return tree[rt]; 40 } 41 int m=(l+r)>>1; 42 if(r1<=m){ 43 return query(l1,r1,ls); 44 } 45 if(l1>m){//l1==m时,两侧都要查询。 46 return query(l1,r1,rs); 47 } 48 return max(query(l1,r1,ls),query(l1,r1,rs)); 49 } 50 void update(int pos,int num,int l=1,int r=n,int rt=1) 51 { 52 if(l==r&&l==pos){ 53 tree[rt]=num; 54 return ; 55 } 56 int m=(l+r)>>1; 57 if(pos<=m) update(pos,num,ls);//pos==m还是要在左边更新 58 else update(pos,num,rs); 59 ph(rt); 60 } 61 int main() 62 { 63 while(~scanf("%d%d",&n,&m)){ 64 memset(a,0,sizeof(a)); 65 memset(tree,0,sizeof(tree));//每次要清空 66 for(int i=1;i<=n;i++) 67 { 68 scanf("%d",&a[i]); 69 } 70 build(); 71 int x,y; 72 while(m--) 73 { 74 scanf("%s%d%d",s,&x,&y); 75 if(s[0]=='Q'){ 76 printf("%d ",query(x,y)); 77 } 78 else{ 79 update(x,y); 80 } 81 } 82 } 83 return 0; 84 }

    YJJ's Salesman  hdu   6447

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1212    Accepted Submission(s): 425


    Problem Description
    YJJ is a salesman who has traveled through western country. YJJ is always on journey. Either is he at the destination, or on the way to destination.
    One day, he is going to travel from city A to southeastern city B. Let us assume that A is (0,0) on the rectangle map and B (109,109). YJJ is so busy so he never turn back or go twice the same way, he will only move to east, south or southeast, which means, if YJJ is at (x,y) now (0x109,0y109), he will only forward to (x+1,y)(x,y+1) or (x+1,y+1).
    On the rectangle map from (0,0) to (109,109), there are several villages scattering on the map. Villagers will do business deals with salesmen from northwestern, but not northern or western. In mathematical language, this means when there is a village k on (xk,yk) (1xk109,1yk109), only the one who was from (xk1,yk1) to (xk,yk) will be able to earn vk dollars.(YJJ may get different number of dollars from different village.)
    YJJ has no time to plan the path, can you help him to find maximum of dollars YJJ can get.
     
    Input
    The first line of the input contains an integer T (1T10),which is the number of test cases.

    In each case, the first line of the input contains an integer N (1N105).The following N lines, the k-th line contains 3 integers, xk,yk,vk (0vk103), which indicate that there is a village on (xk,yk) and he can get vk dollars in that village.
    The positions of each village is distinct.
     
    Output
    The maximum of dollars YJJ can get.
     
    Sample Input
    1 3 1 1 1 1 2 2 3 3 1
     
    Sample Output
    3
     
    Source

     

    单点更新,区间极值
    int t,n,tree[N<<2];
    struct M{
        int x,y,ux,uy,w;
    }mm[N];
    void ph(int rt)
    {
        tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
    }
    void build(int l=1,int r=n,int rt=1)
    {
        if(l==r)
        {
            tree[rt]=0;
            return ;
        }
        int mid=(r+l)>>1;
        build(ls);build(rs);
        ph(rt);
        
    }
    void update(int l1,int num,int l=1,int r=n,int rt=1)
    {
        if(l==r&&l==l1){
            tree[rt]=num;
            return ;
        }
        int mid=(r+l)>>1;
        if(l1<=mid) update(l1,num,ls);
        else update(l1,num,rs);
        ph(rt);
    }
    int query(int l1,int r1,int l=1,int r=n,int rt=1)
    {
        if(l1<=l&&r1>=r) {
            return tree[rt];
        }
        int mid=(r+l)>>1;
        if(r1<=mid)return query(l1,r1,ls);
        if(l1>mid) return query(l1,r1,rs);
        return max(query(l1,r1,ls),query(l1,r1,rs));
    }
    bool  cmp1(M a,M b)
    {
        return a.x<b.x;
    }
    bool cmp2(M a,M b)
    {
        return a.y<b.y;
    }
    bool cmp3(M a,M  b)
    {
        if(a.x!=b.x) return a.x<b.x;
        return a.y>b.y;
        //因为从列的角度考虑最大值,行的话仅需要从左到右
        //但是列要从小到上(大到小) 
                          
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            build();
            gep(i,1,n){
                scanf("%d%d%d",&mm[i].x,&mm[i].y,&mm[i].w);
            }
            sort(mm+1,mm+1+n,cmp1);
            int X=1;
            gep(i,1,n){
                mm[i].ux=X;
                if(mm[i+1].x!=mm[i].x) X++;
            }
            sort(mm+1,mm+1+n,cmp2);
            int Y=1;
            gep(i,1,n){
                mm[i].uy=Y;
                if(mm[i+1].y!=mm[i].y) Y++;
            }
            //以上就是离散化
            sort(mm+1,mm+1+n,cmp3);
            gep(i,1,n ){
                if(mm[i].uy ==1) update(mm[i].uy,mm[i].w);
                else{
                    int maxx=query(1,mm[i].uy-1)+mm[i].w;//从1~mm[i].y-1列的最大值再加上
                    update(mm[i].uy,maxx);
                }
            }
            printf("%d
    ",query(1,n));        
        }
        return 0;
    }
     1 //  // 区间查询,区间更新。
     2 // hdu   1698
     3 #include <iostream>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <string>
     7 #include <algorithm>
     8 #include <utility>
     9 #include <vector>
    10 #include <map>
    11 #include <queue>
    12 #include <stack>
    13 #include <cstdlib>
    14 typedef long long ll;
    15 #define lowbit(x) (x&(-x))
    16 #define ls l,m,rt<<1
    17 #define rs m+1,r,rt<<1|1
    18 using namespace std;
    19 const int N=1e5+9;
    20 int n,q;
    21 ll a[N],tree[N<<2],add[N<<2];
    22 void ph(int rt)
    23 {
    24     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    25 }
    26 void phh(int rt,int len)
    27 {
    28     if(add[rt])
    29     {
    30         add[rt<<1]=add[rt];
    31         add[rt<<1|1]=add[rt];
    32         tree[rt<<1]=add[rt]*(len-(len>>1));
    33         tree[rt<<1|1]=add[rt]*(len>>1);
    34         add[rt]=0;//消除延迟标记
    35     }
    36 }
    37 void build(int l=1,int r=n,int rt=1)
    38 {
    39     if(l==r)
    40     {
    41         tree[rt]=1;
    42         return ;
    43     }
    44     int m=(r+l)>>1;
    45     build(ls);build(rs);
    46     ph(rt);//别忘了
    47 }
    48 void update(int l1,int r1,ll  num,int l=1,int r=n,int rt=1)
    49 {
    50     if(l1<=l&&r1>=r){
    51         add[rt]=num;
    52         tree[rt]=num*(r-l+1);
    53         return ;
    54     }
    55     phh(rt,r-l+1);
    56     int m=(r+l)>>1;
    57     if(l1<=m) update(l1,r1,num,ls);
    58     if(r1>m) update(l1,r1,num,rs);
    59     ph(rt);    
    60 }
    61 ll query(int l1,int r1,int l=1,int r=n,int rt=1)
    62 {
    63     if(l1<=l&&r1>=r)
    64     {
    65         return tree[rt];
    66     }
    67     phh(rt,r-l+1);//不加这句可以求1到n,但是不能求其他的和
    68     ll ans=0;
    69     int m=(r+l)>>1;
    70     if(l1<=m) ans+=query(l1,r1,ls);
    71     if(r1>m) ans+=query(l1,r1,rs);
    72     return ans;
    73 }
    74 int  main()
    75 {
    76     int t;
    77     scanf("%d",&t);
    78     for(int i=1;i<=t;i++){
    79     memset(add,0,sizeof(add));
    80     memset(tree,0,sizeof(tree));
    81     scanf("%d%d",&n,&q);
    82     build();
    83     int x,y,z;
    84     while(q--)
    85     {
    86         scanf("%d%d%d",&x,&y,&z);
    87         update(x,y,z);
    88     }
    89     printf("Case %d: The total value of the hook is %d.
    ",i,query(1,n));
    90      }
    91     return 0;
    92 }
      1 // hdu  1166
      2 // 单点更新,区间求和
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cstring>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <queue>
      9 #include <stack>
     10 #include <cstdlib>
     11 #include <iomanip>
     12 #include <cmath>
     13 #include <cassert>
     14 #include <ctime>
     15 #include <cstdlib>
     16 #include <map>
     17 #include <set>
     18 using namespace std;
     19 #define  ll long long
     20 #define lowbit(x) (x&(-x))
     21 #define max(x,y) (x>=y?x:y)
     22 #define min(x,y) (x<=y?x:y)
     23 #define MAX 100000000000000000
     24 #define MOD 1000000007
     25 #define pi acos(-1.0)
     26 #define ei exp(1)
     27 #define PI 3.1415926535897932384626433832
     28 #define ios() ios::sync_with_stdio(true)
     29 #define inf 1044266558
     30 #define mem(a) (memset(a,0,sizeof(a)))
     31 #define ls l,m,rt<<1
     32 #define rs m+1,r,rt<<1|1
     33 //typedef unsigned long long ll;
     34 map<int,ll>mp;
     35 const int N=5e4+9;
     36 char s[10];
     37 int sum[N<<2],aa[N<<2],t,n;
     38 void  ph(int rt)
     39 {
     40     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     41 }
     42 void build(int l,int r,int rt)
     43 {
     44     if(l==r)
     45     {
     46         //scanf("%d",&sum[rt]);
     47         sum[rt] = aa[l];
     48         return ;
     49     }
     50     int m=(l+r)>>1;
     51     build(ls);
     52     build(rs);
     53     ph(rt);
     54 }
     55 void up(int x,int add,int l,int r,int rt)
     56 {
     57     if(l==r)
     58     {
     59         sum[rt]+=add;
     60         return ;
     61     }
     62     int  m=(l+r)>>1;
     63     if(x<=m)
     64     {
     65         up(x,add,ls);
     66     }
     67     else
     68     {
     69         up(x,add,rs);
     70     }
     71     ph(rt);
     72 }
     73 int qu(int l0,int r0,int l,int r,int rt)
     74 {  // m 是左区间的
     75     if(l0<=l&&r0>=r)
     76     {
     77         return sum[rt];
     78     }
     79     int  m=(l+r)>>1;
     80     int ret=0;
     81     if(l0<=m)
     82     {
     83     ret+=qu(l0,r0,ls);
     84     }
     85     if(r0>m)
     86     {
     87         ret+=qu(l0,r0,rs);//r0==m加左区间
     88         }
     89     //ph(rt);
     90     return  ret;
     91 }
     92 int main()
     93 {
     94     scanf("%d",&t);
     95     for(int i=1;i<=t;i++)
     96     {
     97         scanf("%d",&n);
     98         mem(sum);
     99         mem(aa);
    100         for(int i=1;i<=n;i++) scanf("%lld",&aa[i]);
    101         build(1,n,1);
    102         printf("Case %d:
    ",i);
    103         while(scanf("%s",s))
    104         {
    105              int a,b;
    106             if(s[0]=='E')
    107             {
    108                 break;
    109             }
    110             scanf("%d %d",&a,&b);
    111             if(s[0]=='A')
    112             {
    113 
    114                 up(a,b,1,n,1);
    115             }
    116             else if(s[0]=='Q')
    117             {
    118                 printf("%d
    ",qu(a,b,1,n,1));
    119 
    120             }
    121             else
    122             {
    123                 up(a,-b,1,n,1);
    124             }
    125         }
    126     }
    127     return 0;
    128 }
     1 //  hdu 2795
    // 单点修改,单点查询
    2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <utility> 8 #include <vector> 9 #include <map> 10 #include <queue> 11 #include <stack> 12 #include <cstdlib> 13 typedef long long ll; 14 #define lowbit(x) (x&(-x)) 15 #define ls l,m,rt<<1 16 #define rs m+1,r,rt<<1|1 17 using namespace std; 18 int h,w,n; 19 const int N=2e5+9; 20 int tree[N<<2];//管辖的区间内空余长度的最大值 21 void ph(int rt) 22 { 23 tree[rt]=max(tree[rt<<1],tree[rt<<1|1]); 24 } 25 void build(int l=1,int r=h,int rt=1) 26 { 27 tree[rt]=w; 28 if(l==r) 29 return ; 30 int m=(r+l)>>1; 31 build(ls);build(rs); 32 //初始状态都是w,因此不再更新 33 } 34 int query(int val ,int l=1,int r=h,int rt=1){ 35 if(l==r) { 36 tree[rt]-=val;//最上最左 37 return l; 38 } 39 int m=(r+l)>>1; 40 int ret; 41 ret=(tree[rt<<1]>=val)?query(val,ls):query(val,rs); 42 ph(rt); 43 return ret; 44 } 45 int main() 46 { 47 while(~scanf("%d%d%d",&h,&w,&n)) 48 { 49 if(h>n) h=n;//一行一个最多n行 50 build(); 51 int val; 52 for(int i=0;i<n;i++) 53 { 54 scanf("%d",&val); 55 if(tree[1]<val) printf("-1 ");//无法贴 56 else{ 57 printf("%d ",query(val)); 58 } 59 } 60 } 61 return 0; 62 }
     1 //  牛客小白月赛5
     2 //  I   区间 (interval)
     3 // 区间修改,区间加减,再区间求和
     5 #include <iostream>
     6 #include <cstdio>
     7 #include <cstring>
     8 #include <string>
     9 #include <algorithm>
    10 #include <utility>
    11 #include <vector>
    12 #include <map>
    13 #include <queue>
    14 #include <stack>
    15 #include <cstdlib>
    16 typedef long long ll;
    17 #define lowbit(x) (x&(-x))
    18 #define ls l,m,rt<<1
    19 #define rs m+1,r,rt<<1|1
    20 using namespace std;
    21 const int N=1e6+9;
    22 int n,q;
    23 ll a[N],tree[N<<2],add[N<<2];
    24 void ph(int rt)
    25 {
    26     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    27 }
    28 void phh(int rt,int len)
    29 {
    30     if(add[rt])
    31     { //都是累加的
    32         add[rt<<1]+=add[rt];
    33         add[rt<<1|1]+=add[rt];
    34         tree[rt<<1]+=add[rt]*(len-(len>>1));
    35         tree[rt<<1|1]+=add[rt]*(len>>1);
    36         add[rt]=0;//消除延迟标记
    37     }
    38 }
    39 void build(int l=1,int r=n,int rt=1)
    40 {
    41     if(l==r)
    42     {
    43         tree[rt]=a[l];
    44         return ;
    45     }
    46     int m=(r+l)>>1;
    47     build(ls);build(rs);
    48     ph(rt);//别忘了
    49 }
    50 void update(int l1,int r1,ll  num,int l=1,int r=n,int rt=1)
    51 {
    52     if(l1<=l&&r1>=r){
    53         add[rt]+=num;//注意这些也都是累加的
    54         tree[rt]+=num*(r-l+1);//隐式类型朱转换如:1.0*整型为double
    55         return ;
    56     }
    57     phh(rt,r-l+1);
    58     int m=(r+l)>>1;
    59     if(l1<=m) update(l1,r1,num,ls);
    60     if(r1>m) update(l1,r1,num,rs);
    61     ph(rt);   
    62 }
    63 ll query(int l1,int r1,int l=1,int r=n,int rt=1)
    64 {
    65     if(l1<=l&&r1>=r)
    66     {
    67         return tree[rt];
    68     }
    69     phh(rt,r-l+1);//不加这句可以求1到n,但是不能求其他的和
    70     ll ans=0;
    71     int m=(r+l)>>1;
    72     if(l1<=m) ans+=query(l1,r1,ls);
    73     if(r1>m) ans+=query(l1,r1,rs);
    74     return ans;
    75 }
    76 int  main()
    77 {
    78     scanf("%d%d",&n,&q);
    79     for(int i=1;i<=n;i++)
    80     {
    81         scanf("%lld",&a[i]);
    82     }
    83     build();
    84     int a,b,c;
    85     ll d;
    86     while(q--){
    87         scanf("%d%d%d%lld",&a,&b,&c,&d);
    88         if(a==1){
    89             update(b,c,-d);
    90         }
    91         else{
    92             update(b,c,d);
    93         }
    94     }
    95     int l,r;
    96     scanf("%d%d",&l,&r);
    97     printf("%lld
    ",query(l,r));
    98 }
     1 // zoj 1610  
     2 
     3 
     4 #include <iostream>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <string>
     8 #include <algorithm>
     9 #include <utility>
    10 #include <vector>
    11 #include <map>
    12 #include <queue>
    13 #include <stack>
    14 #include <cstdlib>
    15 typedef long long ll;
    16 #define lowbit(x) (x&(-x))
    17 #define ls l,m,rt<<1
    18 #define rs m+1,r,rt<<1|1
    19 using namespace std;
    20 const int N=8100;
    21 int add[N<<2],num[N<<2];
    22 int n,last;
    23 void ph(int rt)
    24 {
    25     if(add[rt]!=-1){
    26         add[rt<<1]=add[rt];
    27         add[rt<<1|1]=add[rt];
    28         add[rt]=-1;
    29     }
    30 }
    31 void update(int l1,int r1,int x,int l=1,int r=8000,int rt=1)
    32 {
    33     if(l1<=l&&r1>=r){
    34         add[rt]=x;
    35         return ;
    36     }
    37     ph(rt);
    38     int m=(r+l)>>1;
    39     if(l1<=m) update(l1,r1,x,ls);
    40     if(r1>m) update(l1,r1,x,rs);
    41 }
    42 void query(int l=1,int r=8000,int rt=1)
    43 {
    44     if(l==r){
    45         if(add[rt]!=-1&&add[rt]!=last){//连着的区间是一样的
    46             
    47             num[add[rt]]++;
    48         }
    49         last=add[rt];//查询其他的,比较的是右边的。
    50         return ;
    51     }
    52     ph(rt);
    53     int m=(r+l)>>1;
    54     query(ls);query(rs);//整体查询
    55 }
    56 int main()
    57 {    int a,b,c;
    58      
    59     while(~scanf("%d",&n)){//直接拿8000建树,因为输入的n组数据的
    60                            //区间范围不明确。
    61         memset(add,-1,sizeof(add));
    62         memset(num,0,sizeof(num));
    63         //只需要上面的初始化,不再需要build().
    64         for(int i=1;i<=n;i++)
    65         {
    66             scanf("%d%d%d",&a,&b,&c);
    67             update(a+1,b,c);//看成更新点,不连续。
    68         /* 如:
    69             5
    70             0 4 4
    71             0 3 1
    72             3 4 2
    73             0 2 2
    74             0 2 3
    75             0 1 2 3 4
    76             3 3 3 2 2
    77             2到3是区间,区间2,3是1.
    78             因此可以左端+1,看成对点更新,就不会连续了。
    79             */
    80         }
    81         last=-1;
    82         query();
    83         for(int i=0;i<=8000;i++)
    84         {
    85             if(num[i]){
    86                 printf("%d %d
    ",i,num[i]);
    87             }
    88         }
    89         printf("
    ");
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    122. 买卖股票的最佳时机 II-leetcode
    SQL优化
    《C++ Primer Plus》读书笔记之十二—C++中的代码重用
    《C++ Primer Plus》读书笔记之十一—类继承
    《C++ Primer Plus》读书笔记之十—类和动态内存分配
    《C++ Primer Plus》读书笔记之九—使用类
    《C++ Primer Plus》读书笔记之八—对象和类
    一道算法题-换钱
    《C++ Primer Plus》读书笔记之七—内存模型和名称空间
    《C++ Primer Plus》读书笔记之六—函数探幽
  • 原文地址:https://www.cnblogs.com/tingtin/p/9343871.html
Copyright © 2011-2022 走看看