来源: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;
}