比赛时没敲出来,似乎现在敲得还是不好
后来找了份题解,http://www.cnblogs.com/qq1012662902/p/3883614.html 600多msAC 很高效了
参考了之后写了代码 近期在重写一遍
</pre><pre name="code" class="cpp">#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define IN(s) freopen(s,"r",stdin)
const int MAXN = 100000+100;
int gcd(int a, int b)
{
if(!a)return b;
if(!b)return a;
return gcd(b,a%b);
}
int num[MAXN];
struct Node{
int l,r;
int mx,val;
//mx记录最大值,用于剪枝
//val为-1是没有lazy,否则存储需要更新的值v--操作1
//注意因为更新的值是大于等于0的,所以可以这么用
}nodes[MAXN*4];
void pushup(int rt)
{
nodes[rt].mx=max(nodes[ls(rt)].mx,nodes[rs(rt)].mx);
}
void build(int rt, int l, int r)
{
nodes[rt].l=l;
nodes[rt].r=r;
nodes[rt].mx=0;
nodes[rt].val=-1;
if(l == r)
{
nodes[rt].mx=nodes[rt].val=num[l];
return;
}
int mid=(l+r)/2;
build(ls(rt),l,mid);
build(rs(rt),mid+1,r);
pushup(rt);
}
void modify(int rt,int v)//2操作
{
if(nodes[rt].mx<=v)return;
if(nodes[rt].val!=-1)//仍然更新到段--到仅仅有一种更新lazy标记
{
nodes[rt].mx=nodes[rt].val=gcd(nodes[rt].val,v);
//nodes[rt].val=-1;
return;
}
modify(ls(rt),v);
modify(rs(rt),v);
pushup(rt);
}
void update(int rt, int l, int r,int op,int v)
{
//找到区间之后,根据操作做更新
//一种操作的话,当找到对应的
//区间(nodes[rt].l==l && nodes[rt].r==r)之后,
//只标记而不往下更新,直到下次update到这次才将这次的pushdown
//此题中,操作一是赋值,会覆盖操作二,所以直接操作
//如果是操作二,查看之前是不是已经有lazy操作,有的话,先做之前的lazy,
//直到达到一个结点,该节点没有做过lazy标记,那么标记这个节点,停止update‘
if(nodes[rt].l==l && nodes[rt].r==r)
{
if(op==1)
{
nodes[rt].val=v;
nodes[rt].mx=v;//该区间所有的值都变成了v,所以最大值为v
}
else
{
modify(rt,v);
}
return;
}
//pushdown
if(nodes[rt].val!=-1)
{
//此处把mx也更新了,因为gcd(a,b)<=a&&gcd(a,b)<=b
//又因为题目中说了,当要更新的val<num[i]时才更新num[i]为gcd();
//
nodes[ls(rt)].mx=nodes[rs(rt)].mx=nodes[rt].val;
nodes[ls(rt)].val=nodes[rs(rt)].val=nodes[rt].val;
nodes[rt].val=-1;
}
int mid=(nodes[rt].l+nodes[rt].r)/2;
if(r<=mid)update(ls(rt),l,r,op,v);
else
{
if(l>mid)
update(rs(rt),l,r,op,v);
else
{
update(ls(rt),l,mid,op,v);
update(rs(rt),mid+1,r,op,v);
}
}
pushup(rt);
}
void dfs(int rt)
{
if(nodes[rt].l==nodes[rt].r)
{
num[nodes[rt].l]=nodes[rt].val;
return;
}
if(nodes[rt].val!=-1)
{
nodes[ls(rt)].val=nodes[rs(rt)].val=nodes[rt].val;
nodes[rt].val=-1;
}
dfs(ls(rt));
dfs(rs(rt));
}
int main()
{
//IN("hdu4902.txt");
int ncase,n,q,l,v,r;
int op;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
build(1,1,n);
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d%d",&op,&l,&r,&v);
update(1,l,r,op,v);
}
dfs(1);
for(int i=1;i<=n;i++)
printf("%d ",num[i]);
putchar('\n');
}
return 0;
}