zoukankan      html  css  js  c++  java
  • 【吉如一线段树】JZOJ6270. 【省赛模拟8.10】序列

    Description

    在这里插入图片描述
    ai,n<=2e5

    Solution

    • 考虑按照答案分类,假如dd的倍数为a[1],a[2],..a[k1],a[k]a[1],a[2],..a[k-1],a[k],那么区间被1…(a[k-1]-1),(a[2]+1)…n,(a[1]+1)…(a[n]-1)这三个区间包含的区间的答案至少为d,也就是要维护区间取MAX,并求和。
    • 最后求所有区间的答案。
    • 将操作区间左到右排序,用一个吉如一线段树(裸的)直接维护这个操作就好了。
    • 实际上由于每一次对一个前缀取MAX,区间的值实际上是单调不升的,二分一下就好了(用一个set).

    吉如一线段树

    • 据说是nlogn~nlog2n的。
    • 我们只考虑求最大值(最小值类似),以及区间求和。
    • 每一个节点记录一个最小值和严格次小值(初值为inf),区间和以及区间最小值的个数。
    • 假设当前修改的是v,v如果小于等于最小值肯定不用考虑。
    • v如果大于最小值并严格小于次小值,那么考虑将最小值的那一部分改为v,再计算贡献。
    • 否则大于等于次小值就递归下去。
    • 根据一些势能分析这样子做事不会T的(雾),也许之后会补这一部分的知识吧。
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #define maxn 200005
    #define maxm 1000005
    #define LL long long 
    using namespace std;
    
    int n,i,j,k,a[maxn],mx,tot,w;
    int p0[maxn],p1[maxn],q0[maxn],q1[maxn];
    int u0[maxn],u1[maxn],v0[maxn],v1[maxn];
    struct opr{
    	int l,r,x;
    	opr(int _l=0,int _r=0,int _x=0){l=_l,r=_r,x=_x;}
    } p[20*maxn];
    int cmp(opr a,opr b){return a.l<b.l;}
    
    LL t[maxm],ans;
    int mi0[maxm],mi1[maxm],cnt[maxm],tag[maxm];
    
    void Min(int &x,int y){x=min(x,y);}
    void Max(int &x,int y){x=max(x,y);}
    
    void add0(int i,int x){
    	if (x<p0[i]) p1[i]=p0[i],p0[i]=x; else 
    	if (x<p1[i]) p1[i]=x;
    	if (x>q0[i]) q1[i]=q0[i],q0[i]=x; else
    	if (x>q1[i]) q1[i]=x;
    }
    
    void add1(int i,int x,int t){
    	if (t==0){
    		if (x<u0[i]) u1[i]=u0[i],u0[i]=x; else 
    		if (x<u1[i]) u1[i]=x;		
    	}
    	if (t==1){
    		if (x>v0[i]) v1[i]=v0[i],v0[i]=x; else
    		if (x>v1[i]) v1[i]=x;		
    	}
    }
    
    void add2(int i,int j){
    	if (p0[j]!=maxn) add1(i,p0[j],0);
    	if (p1[j]!=maxn) add1(i,p1[j],0);
    	if (q0[j]) add1(i,q0[j],1);
    	if (q1[j]) add1(i,q1[j],1);
    }
    
    void insert(int l,int r,int x){
    	if (l<=r) tot++,p[tot]=opr(l,r,x);
    }
    
    void maketree(int x,int l,int r){
    	t[x]=0,mi0[x]=0,mi1[x]=maxn,tag[x]=0,cnt[x]=r-l+1;
    	if (l==r) return;
    	int mid=(l+r)>>1;
    	maketree(x<<1,l,mid),maketree(x<<1|1,mid+1,r);
    }
    
    void doit(int x,int v){
    	if (v<=mi0[x]) return;
    	t[x]+=(v-mi0[x])*cnt[x];
    	mi0[x]=v;
    }
    
    void downtag(int x,int l,int r){
    	doit(x,tag[x]);
    	if (l<r){
    		Max(tag[x<<1],tag[x]);
    		Max(tag[x<<1|1],tag[x]);
    	}
    	tag[x]=0;
    }
    
    void upd(int x){
    	int l=x<<1,r=x<<1|1;
    	t[x]=t[l]+t[r];
    	mi0[x]=min(mi0[l],mi0[r]);
    	mi1[x]=min(mi1[l],mi1[r]);
    	if (mi0[x]^mi0[l]) Min(mi1[x],mi0[l]);
    	if (mi0[x]^mi0[r]) Min(mi1[x],mi0[r]);
    	cnt[x]=(mi0[l]==mi0[x])*cnt[l]+(mi0[r]==mi0[x])*cnt[r];
    }
    
    void change(int x,int l,int r,int ll,int rr,int v){
    	if (tag[x]) downtag(x,l,r);
    	if (l>rr||r<ll||mi0[x]>=v) return;
    	if (ll<=l&&r<=rr&&mi1[x]>v){
    		tag[x]=max(tag[x],v),downtag(x,l,r); 
    		return;
    	}
    	int mid=(l+r)>>1;
    	change(x<<1,l,mid,ll,rr,v);
    	change(x<<1|1,mid+1,r,ll,rr,v);
    	upd(x);
    }
    
    LL find(int x,int l,int r,int ll,int rr){
    	if (tag[x]) downtag(x,l,r);
    	if (l>rr||r<ll) return 0;
    	if (ll<=l&&r<=rr) return t[x];
    	int mid=(l+r)>>1;
    	return find(x<<1,l,mid,ll,rr)+find(x<<1|1,mid+1,r,ll,rr);
    }
    
    int main(){
    	scanf("%d",&n);
    	for(i=1;i<maxn;i++) p0[i]=p1[i]=maxn,q0[i]=q1[i]=0;
    	for(i=1;i<=n;i++) {
    		scanf("%d",&a[i]);
    		add0(a[i],i),mx=max(mx,a[i]);
    	}
    	for(i=1;i<=mx;i++) {
    		u0[i]=u1[i]=maxn,v0[i]=v1[i]=0;
    		for(j=i;j<=mx;j+=i) add2(i,j);
    		insert(u0[i]+1,v0[i]-1,i);
    		insert(1,v1[i]-1,i);
    		insert(u1[i]+1,n,i);
    	}
    	sort(p+1,p+1+tot,cmp);
    	maketree(1,1,n); j=1;
    	for(i=1;i<=n;i++){
    		for(;j<=tot&&p[j].l==i;j++) 
    			change(1,1,n,p[j].l,p[j].r,p[j].x);
    		ans+=find(1,1,n,i,n);
    	}
    	printf("%lld
    ",ans);
    }
    
    
  • 相关阅读:
    攻防世界-web-Web_php_unserialize(PHP反序列化漏洞)
    攻防世界-web-unfinish(sql二次注入)
    【第19次CCF CSP认证】Markdown渲染器 (模拟)
    c++类 构造函数 析构函数 拷贝构造函数
    linux快速配置网络脚本
    编译安装openresty
    编译openresty出现的报错
    编译安装libmcrypt
    编译安装PHP支持环境libiconv
    Spring Boot-内置的Tomcat服务器配置详解
  • 原文地址:https://www.cnblogs.com/DeepThinking/p/13090972.html
Copyright © 2011-2022 走看看