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