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("%\n"); 93 } 94 }
时间: 2024-10-06 12:49:59