1 10 16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709 10 1 3 6 74243042 2 4 8 16531729 1 3 4 1474833169 2 1 8 1131570933 2 7 9 1505795335 2 3 7 101929267 1 4 10 1624379149 2 2 8 2110010672 2 6 7 156091745 1 2 5 937186357
16807 937186357 937186357 937186357 937186357 1 1 1624379149 1624379149 1624379149
题目大意:
解题思路:给定n个数,m个操作,”1 L R X“ 表示把LR区间的数同时置为X,"2 L R X "表示把LR区间大于X的数比如Y置为gcd(X,Y)。
解题代码:区间操作,一下子就想到了线段树,但是注意线段树的优化,只要维护记录最大值的maxc,以及bool记录这段是否相等这两个变量即可,详细还请参照我的代码。
#include <iostream> #include <cstdio> using namespace std; const int maxn=110000; int n,m,d[maxn]; struct tree{ int l,r,maxc; bool flag; }a[maxn*4]; int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } void push_down(int k){ if(a[k].flag){ a[2*k+1].flag=a[2*k].flag=true; a[2*k+1].maxc=a[2*k].maxc=a[k].maxc; } } void push_up(int k){ a[k].maxc=max(a[2*k].maxc,a[2*k+1].maxc); if(a[2*k].flag && a[2*k+1].flag && a[2*k].maxc==a[2*k+1].maxc) a[k].flag=true; else a[k].flag=false; } void build(int l,int r,int k){ a[k].l=l; a[k].r=r; if(l==r){ a[k].maxc=d[r]; a[k].flag=true; }else{ int mid=(l+r)/2; build(l,mid,2*k); build(mid+1,r,2*k+1); push_up(k); } } void insert1(int l,int r,int k,int x){//change data in l~r to x if(l<=a[k].l && a[k].r<=r){ a[k].maxc=x; a[k].flag=true; }else{ push_down(k); int mid=(a[k].l+a[k].r)/2; if(r<=mid) insert1(l,r,2*k,x); else if(l>=mid+1) insert1(l,r,2*k+1,x); else{ insert1(l,mid,2*k,x); insert1(mid+1,r,2*k+1,x); } push_up(k); } } void insert2(int l,int r,int k,int x){//change data >x to gcd(data,x) if(l<=a[k].l && a[k].r<=r){ if(a[k].maxc<=x) return; if(a[k].flag){ a[k].maxc=gcd(a[k].maxc,x); }else{ push_down(k); int mid=(a[k].l+a[k].r)/2; insert2(l,mid,2*k,x); insert2(mid+1,r,2*k+1,x); push_up(k); } }else{ push_down(k); int mid=(a[k].l+a[k].r)/2; if(r<=mid) insert2(l,r,2*k,x); else if(l>=mid+1) insert2(l,r,2*k+1,x); else{ insert2(l,mid,2*k,x); insert2(mid+1,r,2*k+1,x); } push_up(k); } } void query(int l,int k){ if(a[k].l==a[k].r) printf("%d ",a[k].maxc); else{ push_down(k); int mid=(a[k].l+a[k].r)/2; if(l<=mid) query(l,2*k); else query(l,2*k+1); push_up(k); } } void solve(){ build(0,n-1,1); scanf("%d",&m); for(int i=0;i<m;i++){ int op,l,r,x; scanf("%d%d%d%d",&op,&l,&r,&x); if(op==1) insert1(l-1,r-1,1,x); else insert2(l-1,r-1,1,x); } for(int i=0;i<n;i++){ query(i,1); } printf("\n"); } int main(){ int T; scanf("%d",&T); while(T-- >0){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&d[i]); solve(); } return 0; }
HDU 4902 Nice boat(数据结构-线段树),布布扣,bubuko.com
原文:http://blog.csdn.net/a1061747415/article/details/38589181