时限15s,根本就是怎么水怎么过啊。
维护两个标记,一个赋值一个取gcd,保证一个节点只有一种标记,多余的向下pushdown,由于只要最后结果,不用pushup,直接水水注意细节就行了。
PE了一次,格式控制挺反人类的。
附代码:
#include
#include
#include
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define delf int m=(l+r)>>1
const int MAX=100010;
int s[MAX<<2];
int g[MAX<<2];
int n,q;
void swap(int &a,int &b)
{
if (ag[rt])
g[rt<<1]=gcd(g[rt<<1],g[rt]);
}
}
else if (s[rt<<1]!=-1)
{
if (s[rt<<1]>g[rt])
{
s[rt<<1]=gcd(s[rt<<1],g[rt]);
}
}
else
g[rt<<1]=g[rt];
if (g[rt<<1|1]!=-1)
{
if (m+1!=r)
{
pushdown(rson);
g[rt<<1|1]=g[rt];
}
else
{
if (g[rt<<1|1]>g[rt])
g[rt<<1|1]=gcd(g[rt<<1],g[rt]);
}
}
else if (s[rt<<1|1]!=-1)
{
if (s[rt<<1|1]>g[rt])
{
s[rt<<1|1]=gcd(s[rt<<1|1],g[rt]);
}
}
else
g[rt<<1|1]=g[rt];
g[rt]=-1;
}
return ;
}
void build(int l,int r,int rt)
{
s[rt]=g[rt]=-1;
if (l==r)
{
scanf("%d",&s[rt]);
return ;
}
delf;
build(lson);
build(rson);
return ;
}
void update1(int L,int R,int x,int l,int r,int rt) //赋值操作
{
if (L<=l&&r<=R)
{
s[rt]=x;
g[rt]=-1;
return ;
}
pushdown(l,r,rt);
delf;
if (L<=m)
update1(L,R,x,lson);
if (R>m)
update1(L,R,x,rson);
return ;
}
void update2(int L,int R,int x,int l,int r,int rt) //gcd操作
{
if (L<=l&&r<=R)
{
if (s[rt]!=-1) //如果存在赋值操作,将新的gcd替代赋值操作变成新的赋值操作
{
if (s[rt]>x)
{
s[rt]=gcd(x,s[rt]);
}
}
else if (g[rt]!=-1) //如果存在gcd操作,将gcd操作向下更新,记录新的gcd操作
{
pushdown(l,r,rt);
g[rt]=x;
}
else
g[rt]=x; //否则,记录新的gcd操作
return ;
}
pushdown(l,r,rt);
delf;
if (L<=m)
update2(L,R,x,lson);
if (R>m)
update2(L,R,x,rson);
return ;
}
void query(int l,int r,int rt)
{
if (l==r)
{
if (s[rt]!=-1)
printf("%d",s[rt]);
else
printf("%d",g[rt]);
printf(" ");
return ;
}
delf;
pushdown(l,r,rt);
query(lson);
query(rson);
return ;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
build(1,n,1);
scanf("%d",&q);
while (q--)
{
int t,l,r,x;
scanf("%d%d%d%d",&t,&l,&r,&x);
if (t==1)
update1(l,r,x,1,n,1);
if (t==2)
update2(l,r,x,1,n,1);
}
query(1,n,1);
printf("\n");
}
}