HDU 4902 (线段树)

Problem Nice boat(HDU 4902)

题目大意 

  维护一个序列,两种操作。

  第一种操作,将一段区间[l,r]赋值为x。

  第二种操作,将一段区间[l,r]中大于等于x的数与x求gcd。

  询问所有操作结束后的序列。

解题分析

  用线段树开一个标记same,表示这段区间中的数是否相同,若相同则为该数,否则为-1。

  对于第二种操作,对于覆盖区间内的same不为-1的子区间暴力修改。

  虽然时限有15s,但貌似跑得挺快的,只用了1s,不知是数据水还是什么缘故。

参考程序

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 #define N 100008
 8 #define lson l,m,rt<<1
 9 #define rson m+1,r,rt<<1|1
10 int same[N*4];
11 int n;
12 
13 int gcd(int x,int y){
14     return y ? gcd(y,x % y): x;
15 }
16 
17 void pushup(int rt){
18     if (same[rt<<1]==same[rt<<1|1]) same[rt]=same[rt<<1];
19     else same[rt]=-1;
20 }
21 
22 void pushdown(int rt){
23     if (~same[rt]){
24         same[rt<<1]=same[rt<<1|1]=same[rt];
25         same[rt]=-1;
26     }
27 }
28 
29 void build(int l,int r,int rt){
30     same[rt]=-1;
31     if (l==r){
32         scanf("%d",&same[rt]);
33         return;
34     }
35     int m=(l+r) / 2;
36     build(lson);
37     build(rson);
38     pushup(rt);
39 }
40 
41 void update_1(int L,int R,int val,int l,int r,int rt){
42     if (L<=l && r<=R){
43         same[rt]=val;
44         return;
45     }
46     pushdown(rt);
47     int m=(l+r) /2;
48     if (L<=m) update_1(L,R,val,lson);
49     if (m< R) update_1(L,R,val,rson);
50     pushup(rt);
51 }
52 
53 void update_2(int L,int R,int val,int l,int r,int rt){
54     if (L<=l && r<=R){
55         if (~same[rt]){
56             if (same[rt]>=val) same[rt]=gcd(same[rt],val);
57             return;
58         }
59     }
60     pushdown(rt);
61     int m=(l+r) /2;
62     if (L<=m) update_2(L,R,val,lson);
63     if (m< R) update_2(L,R,val,rson);
64     pushup(rt);
65 }
66 
67 void query(int l,int r,int rt){
68     if (l==r){
69         printf("%d ",same[rt]);
70         return;
71     }
72     pushdown(rt);
73     int m=(l+r) / 2 ;
74     query(lson);
75     query(rson);
76 }
77 
78 int main(){
79     int T;
80     scanf("%d",&T);
81     while (T--){
82         scanf("%d",&n);
83         build(1,n,1);
84         int type,a,b,val,q;
85         scanf("%d",&q);
86         while (q--){
87             scanf("%d %d %d %d",&type,&a,&b,&val);
88             if (type==1) update_1(a,b,val,1,n,1);
89             if (type==2) update_2(a,b,val,1,n,1);
90         }
91         query(1,n,1);
92         printf("%
");
93     }
94 }
View Code
原文地址:https://www.cnblogs.com/rpSebastian/p/5719777.html