POJ 2777 && ZOJ 1610 &&HDU 1698 --线段树--区间更新

直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧

直接先上链接了

    touch me

    touch me

    touch me

关于涉及到区间的修改 -- 区间更新的话 分为 增减 或者 修改

主要就是个 laze 标记 就是延迟更新

对于区间更新的写法 一般是有2种 其一 仔细划分到每个细小的区间    另一 粗略划分

反正 ==我的代码里会给出2种写法 看自己喜好

hdu

 1 //线段树 成段更新 ---> 替换    根结点的查询
 2
 3 #include <iostream>
 4 using namespace std;
 5
 6 const int size = 100010;
 7
 8 struct data
 9 {
10     int l;
11     int r;
12     int flag;
13     int sum;
14 }tree[ size*3 ];
15
16 void create( int root , int l , int r )
17 {
18     int mid = l + (r-l)/2;
19     tree[root].l = l;
20     tree[root].r = r;
21     tree[root].flag = 0;
22     if( l==r )
23     {
24         tree[root].sum = 1;
25         return;
26     }
27     create( root<<1 , l , mid );
28     create( root<<1|1 , mid+1 , r );
29     tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
30 }
31
32 void add( int root , int len  )
33 {
34     tree[root<<1].flag = tree[root<<1|1].flag = tree[root].flag ;
35     tree[root<<1].sum = ( len - len/2 ) * tree[root].flag ;
36     tree[root<<1|1].sum = len/2*tree[root].flag;
37     tree[root].flag = 0;
38 }
39
40 void update( int root , int L , int R , int num )
41 {
42     int mid = tree[root].l + ( tree[root].r - tree[root].l ) / 2;
43     if( tree[root].l == L && tree[root].r==R )
44     {
45         tree[root].flag= num;
46         tree[root].sum = num * ( tree[root].r - tree[root].l + 1 );
47         return;
48     }
49     if( tree[root].flag )
50     {
51         add( root , tree[root].r-tree[root].l+1 );
52     }
53     if( R<=mid ) // 左子树
54     {
55         update( root<<1 , L , R , num );
56     }
57     else if( L>=mid+1 ) // 右子树
58     {
59         update( root<<1|1 , L , R , num );
60     }
61     else // 覆盖左右 子树
62     {
63         update( root<<1 , L , mid , num );
64         update( root<<1|1 , mid+1 , R , num );
65     }
66     tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
67 }
68
69 int main()
70 {
71     int t , n , oper;
72     int L , R , num;
73     while( ~scanf("%d",&t) )
74     {
75         for( int i = 1 ; i<=t ; i++ )
76         {
77             scanf( "%d",&n );
78             scanf( "%d",&oper );
79             create( 1 , 1 , n );
80             while( oper-- )
81             {
82                 scanf( "%d %d %d",&L,&R,&num );
83                 update( 1 , L , R , num );
84             }
85             printf( "Case %d: The total value of the hook is %d.\n",i,tree[1].sum );
86         }
87     }
88     return 0;
89 }

POJ

  1 //线段树--区间更新--替换 区间查询---B
  2 #include <iostream>
  3 #include <algorithm>
  4 using namespace std;
  5
  6 int sum;
  7 const int size = 100010;
  8 struct data
  9 {
 10     int l;
 11     int r;
 12     int color;
 13     bool flag;
 14 }tree[size*3];
 15
 16 void create( int root , int l , int r )
 17 {
 18     int mid = ( l + r ) / 2;
 19     tree[root].l = l;
 20     tree[root].r = r;
 21     tree[root].color = 1;
 22     tree[root].flag = false;
 23     if( l==r )
 24     {
 25         return;
 26     }
 27     create( root<<1 , l , mid );
 28     create( root<<1|1 , mid+1 , r );
 29 }
 30
 31 void add( int root )
 32 {
 33     tree[root<<1].flag = true;
 34     tree[root<<1|1].flag = true;
 35     tree[root<<1].color = tree[root].color;
 36     tree[root<<1|1].color = tree[root].color;
 37     tree[root].flag = false;
 38 }
 39
 40 void update( int root , int L , int R , int num )
 41 {
 42     int mid = ( tree[root].l + tree[root].r ) / 2;
 43     if( tree[root].l == L && tree[root].r ==R )
 44     {
 45         tree[root].flag = true;
 46         tree[root].color = num;
 47         return;
 48     }
 49     if( tree[root].color == num )
 50     {
 51         return;
 52     }
 53     if( tree[root].flag )
 54     {
 55         add( root );
 56     }
 57     if( L>=mid+1 )
 58     {
 59         update( root<<1|1 , L , R , num );
 60     }
 61     else if( R<=mid )
 62     {
 63         update( root<<1 , L , R , num );
 64     }
 65     else
 66     {
 67         update( root<<1 , L , mid , num );
 68         update( root<<1|1 , mid+1 , R , num );
 69     }
 70     tree[root].color = tree[root<<1].color | tree[root<<1|1].color;
 71 }
 72
 73 void query( int root , int L , int R )
 74 {
 75     int mid = ( tree[root].l + tree[root].r ) / 2;
 76     if( tree[root].l ==L && tree[root].r ==R )
 77     {
 78         sum |= tree[root].color;
 79         return;
 80     }
 81     if( tree[root].flag )
 82     {
 83         add( root );
 84     }
 85     if( L>=mid+1 )
 86     {
 87         query( root<<1|1 , L , R );
 88     }
 89     else if( R<=mid )
 90     {
 91         query( root<<1 , L , R );
 92     }
 93     else
 94     {
 95         query( root<<1 , L , mid );
 96         query( root<<1|1 , mid+1 , R );
 97     }
 98 }
 99
100 int main()
101 {
102     int cnt;
103     int n , m , oper;
104     char ch;
105     int L , R , num;
106     while( ~scanf("%d %d",&n,&m) )
107     {
108         create( 1 , 1 , n );
109         scanf( "%d",&oper );
110         while( oper-- )
111         {
112             getchar();
113             scanf( "%c",&ch );
114             if( ch==‘C‘ )
115             {
116                 scanf( "%d %d %d",&L,&R,&num );
117                 if( L>R )
118                 {
119                     swap( L ,R );
120                 }
121                 update( 1 , L , R , 1<<(num-1) );
122             }
123             else
124             {
125                 scanf( "%d %d",&L,&R );
126                 if( L>R )
127                 {
128                     swap( L , R );
129                 }
130                 cnt = sum = 0;
131                 query( 1 , L , R );
132                 while( sum )
133                 {
134                     if( sum&1 )
135                     {
136                         cnt++;
137                     }
138                     sum>>=1;
139                 }
140                 printf( "%d\n",cnt );
141             }
142         }
143     }
144     return 0;
145 }

ZOJ

  1 //线段树 --区间更新-替换  -- A
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 using namespace std;
  6
  7 int n;
  8 const int size = 8080;
  9 struct data
 10 {
 11     int l;
 12     int r;
 13     int flag;
 14 }tree[size*3];
 15 int color[size];
 16 int avoid;
 17 int cnt[size];
 18
 19 void create( int root , int l , int r )
 20 {
 21     int mid = ( l + r ) / 2;
 22     tree[root].l = l;
 23     tree[root].r = r;
 24     tree[root].flag = -1;
 25     if( l==r )
 26     {
 27         return;
 28     }
 29     create( root<<1 , l , mid );
 30     create( root<<1|1 , mid+1 , r );
 31 }
 32
 33 void add( int root )
 34 {
 35     tree[root<<1].flag = tree[root<<1|1].flag = tree[root].flag;
 36     tree[root].flag = -1;
 37 }
 38
 39 void update( int root , int L , int R , int num )
 40 {
 41     int mid = ( tree[root].l + tree[root].r )/2;
 42      if( tree[root].flag == num )
 43         return;
 44     if( tree[root].l>=L && tree[root].r<=R )
 45     {
 46         tree[root].flag = num;
 47         return;
 48     }
 49     if( tree[root].flag!=-1 )
 50     {
 51         add( root );
 52     }
 53     /*
 54     if( R<=mid )
 55     {
 56         update( root<<1 , L , R , num );
 57     }
 58     else if( L>=mid+1 )
 59     {
 60         update( root<<1|1 , L , R , num );
 61     }
 62     else
 63     {
 64         update( root<<1 , L , mid , num );
 65         update( root<<1|1 , mid+1 , R , num );
 66     }
 67     */
 68     if( L<=mid )
 69     {
 70         update( root<<1 , L , R , num );
 71     }
 72     if( R>mid )
 73     {
 74         update( root<<1|1 , L , R , num );
 75     }
 76     if( tree[root<<1].flag == tree[root<<1|1].flag && tree[root<<1].flag!=-1 )
 77     {
 78         tree[root].flag = tree[root<<1].flag;
 79     }
 80 }
 81
 82 void solve( int root )
 83 {
 84     if( tree[root].flag!=-1 )
 85     {
 86         //cout<<"root"<<root<<endl;
 87         for( int i = tree[root].l ; i<=tree[root].r ; i++ )
 88         {
 89             color[i] = tree[root].flag;
 90             //cout<<"color:"<<color[i]<<endl;
 91         }
 92         return;
 93     }
 94     if( tree[root].l == tree[root].r )
 95         return;
 96     solve( root<<1 );
 97     solve( root<<1|1 );
 98 }
 99
100 void getAns()
101 {
102     int former = -1;
103     for( int i = 0 ; i<size ; i++ )
104     {
105         if( former != color[i] )
106         {
107             former = color[i];
108             cnt[former]++;
109             //cout<<"数量"<<cnt[former]<<"   former:"<<former<<endl;
110         }
111     }
112     for( int i = 0 ; i<size ; i++ )
113     {
114         if( cnt[i]!=0 )
115         {
116             printf( "%d %d\n",i,cnt[i] );
117         }
118     }
119     printf( "\n" );
120 }
121
122 int main()
123 {
124     int L , R , num;
125     while( ~scanf("%d",&n) )
126     {
127         memset( color , -1 , sizeof(color) );
128         memset( cnt , 0 , sizeof(cnt) );
129         create(1,0,size);
130         for( int i = 0 ; i<n ; i++ )
131         {
132             scanf( "%d %d %d",&L,&R,&num );
133             update( 1 , L , R-1 , num );
134         }
135         solve(1);
136         getAns();
137     }
138     return 0;
139 }

today:

  I am ingratiated by the sunset because of her sensitivity
  As she tries to push the darkness back for just a moment more.
  But like so many times before…To no avail!

POJ 2777 && ZOJ 1610 &&HDU 1698 --线段树--区间更新

时间: 2024-10-27 10:09:57

POJ 2777 && ZOJ 1610 &&HDU 1698 --线段树--区间更新的相关文章

HDU(1698),线段树区间更新

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 区间更新重点在于懒惰标记. 当你更新的区间就是整个区间的时候,直接sum[rt] = c*(r-l+1);col[rt] = c:后面的子区间就不管了,当你下次更新某一个区间的时候,把col[rt]从顶往下推(也没有推到底),推到合适的位置,刚好这个位置是我要更新的区间的子区间(可能被横跨了)就停下来. 在这里感谢网上的大牛,感谢杰哥,彬哥.我才能AC. Just a Hook Time Li

HDU 1698 (线段树 区间更新) Just a Hook

有m个操作,每个操作 X Y Z是将区间[X, Y]中的所有的数全部变为Z,最后询问整个区间所有数之和是多少. 区间更新有一个懒惰标记,set[o] = v,表示这个区间所有的数都是v,只有这个区间被分开的时候再往下传递. 1 #include <cstdio> 2 3 const int maxn = 100000 + 10; 4 int sum[maxn << 2], set[maxn << 2]; 5 6 int n, qL, qR, m, v; 7 8 void

hdu 1698 线段树 区间更新

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 36313    Accepted Submission(s): 17713 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing

HDU 4578 线段树区间更新(确定区间操作的优先级)

HDU 4578 线段树区间更新 操作有: 区间所有数add(c) 区间所有数mul(c) 区间所有数set(c) 查询有: 区间所有数的p次方和(p>= 1 && p <= 3) 关键是区间更新的三种操作的优先级的确定清楚set>mul>add 关键是:down和update中对区间的更新操作是一回事,可以写成函数方便编程 //#pragma warning (disable: 4786) //#pragma comment (linker, "/STA

Just a Hook HDU - 1698Just a Hook HDU - 1698 线段树区间替换

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1e5+10; struct node{ int l,r; int sum; int add; }tr[N*4]; void pushdown(int root) { if (tr[root].add)

HDU 3016 线段树区间更新+spfa

Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1836    Accepted Submission(s): 665 Problem Description The Game “Man Down 100 floors” is an famous and interesting game.You can enjoy th

POJ 2777 Count Color (线段树区间更新加查询)

Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a very long board with length L centimeter, L is a positive integer, so we can evenly d

HDU 1698 Just a Hook (线段树,区间更新)

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17214    Accepted Submission(s): 8600 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing f

ZOJ 1610 Count the Colors (线段树区间更新)

题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头输出. //ZOJ 1610 #include <cstdio> #include <cstring> #include <iostream> using namespace std ; int p[8010*4],lz[8010*4] ,hashh[8010*4],has