每次区间改成一个数,或者所有>=x的数和一个数x取gcd
和一个数取gcd大概log次就取成1了
又有区间覆盖
线段树维护一下这个区间是不是全部相同,全部相同就一起改否则递归下去暴力改
复杂度大概是nlog^2的?
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int gcd(int a,int b){return !a?b:gcd(b%a,a);}
const int maxn = 110000;
int n,m;
int a[maxn];
struct segment{int mx,same,flag;}seg[maxn<<2];
void pushup(const int x)
{
int lc=x<<1,rc=lc|1;
seg[x].mx=seg[lc].mx>seg[rc].mx?seg[lc].mx:seg[rc].mx;
seg[x].same=seg[lc].same&seg[rc].same&(seg[lc].mx==seg[rc].mx);
}
void pushdown(const int x)
{
if(seg[x].flag)
{
int fl=seg[x].flag; seg[x].flag=0;
int lc=x<<1,rc=lc|1;
seg[lc].same=seg[rc].same=1;
seg[lc].mx=seg[rc].mx=fl;
seg[lc].flag=seg[rc].flag=fl;
}
}
void build(const int x,const int l,const int r)
{
seg[x].flag=0;
if(l==r) { seg[x].mx=a[l]; seg[x].same=1; return; }
int mid=l+r>>1;
build(x<<1,l,mid); build(x<<1|1,mid+1,r);
pushup(x);
}
void output(const int x,const int l,const int r)
{
if(l==r) { printf("%d ",seg[x].mx); return; }
pushdown(x);
int mid=l+r>>1;
output(x<<1,l,mid); output(x<<1|1,mid+1,r);
}
int lx,rx,c;
void cover(const int x,const int l,const int r)
{
if(rx<l||r<lx) return;
if(lx<=l&&r<=rx)
{
seg[x].mx=c; seg[x].same=1; seg[x].flag=c;
return;
}
pushdown(x);
int mid=l+r>>1;
cover(x<<1,l,mid); cover(x<<1|1,mid+1,r);
pushup(x);
}
void upd(const int x,const int l,const int r)
{
if(rx<l||r<lx||seg[x].mx<=c) return;
if(lx<=l&&r<=rx&&seg[x].same)
{
seg[x].mx=seg[x].flag=gcd(seg[x].mx,c);
return;
}
pushdown(x);
int mid=l+r>>1,lc=x<<1,rc=lc|1;
upd(x<<1,l,mid); upd(x<<1|1,mid+1,r);
pushup(x);
}
int main()
{
int tcase; scanf("%d",&tcase);
while(tcase--)
{
scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int ti; scanf("%d%d%d%d",&ti,&lx,&rx,&c);
if(ti==1) cover(1,1,n);
else upd(1,1,n);
}
output(1,1,n);
putchar('\n');
}
return 0;
}