题目:hdoj 4902 Nice boat
来源:2014 Multi-University Training Contest 4
题意:给出n个数,有两种操作,第一种是给l--r区间全部替换为x,第二种操作是给 l---r 区间上比x大的替换为gcd(x,num),求最后区间的值。
分析:很明显的线段是入门题目,当然定位也是签到题,刚学了线段树,没写过,比赛的时候把一个地方写错了。导致一直wa、、、
这个题目第一种操作直接更新到一段区间上x,第二种操作同样也更新到区间上,注意往下找的时候一定要更新一次。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <string> #include <algorithm> #include <vector> #include <queue> #include <list> using namespace std; #define Del(a,b) memset(a,b,sizeof(a)) const long long N = 110000; long long a[N]; long long gcd(long long x,long long y) { if(y==0) return x; else return gcd(y,x%y); } struct Node { long long l,r; long long x; }; Node tree[N*5]; void build(long long l,long long r,long long v) { tree[v].l=l; tree[v].r=r; if(l==r) { tree[v].x=a[l]; return ; } long long mid=(l+r)>>1; build(l,mid,v*2); build(mid+1,r,v*2+1); } void push_down(int o) //向下更新 { tree[o+o].x=tree[o+o+1].x=tree[o].x; tree[o].x=0; //注意这里写法 } void update(long long l,long long r,long long val,long long o) { if(tree[o].l==l&&tree[o].r==r) { tree[o].x=val; return ; } if(tree[o].x>0) push_down(o); long long mid=(tree[o].l+tree[o].r)>>1; if(r<=mid) update(l,r,val,o+o); else if(l>mid) update(l,r,val,o+o+1); else { update(l,mid,val,o*2); update(mid+1,r,val,o*2+1); } } void query(long long l,long long r,long long val,long long o) { if(tree[o].l==l && tree[o].r==r && tree[o].x!=0) { if(tree[o].x>val) tree[o].x=gcd(tree[o].x,val); return ; } if(tree[o].x>0) push_down(o); long long mid=(tree[o].l+tree[o].r)>>1; if(r<=mid) query(l,r,val,o+o); else if(l>mid) query(l,r,val,o+o+1); else { query(l,mid,val,o*2); query(mid+1,r,val,o*2+1); } } void get_ans(long long l,long long r,long long o) { if(tree[o].l==tree[o].r) { a[l]=tree[o].x; return ; } if(tree[o].x>0) push_down(o); long long mid=(tree[o].l+tree[o].r)>>1; if(r<=mid) get_ans(l,r,o+o); else if(l>mid) get_ans(l,r,o+o+1); else { get_ans(l,mid,o*2); get_ans(mid+1,r,o*2+1); } } int main() { //freopen("Input.txt","r",stdin); long long T; scanf("%I64d",&T); while(T--) { Del(tree,0); long long n; scanf("%I64d",&n); for(int i=1; i<=n; i++) scanf("%I64d",&a[i]); build(1,n,1); long long m; scanf("%I64d",&m); while(m--) { long long x,y,z,val; scanf("%I64d%I64d%I64d%I64d",&x,&y,&z,&val); if(x==1) update(y,z,val,1); else if(x==2) query(y,z,val,1); } get_ans(1,n,1); for(int i=1; i<=n; i++) printf("%I64d ",a[i]); printf("\n"); } return 0; }