zoukankan      html  css  js  c++  java
  • CF1539F Strange Array

    这玩意为啥是紫。

    考虑对每个小于(x)的数值设为1,大于(x)的数值设为-1.
    那么对于答案要求的就是绝对值最大的连续段。
    线段树是很显然的。

    考虑我们不能对每个数都进行一遍重构,这样就退化到了(O(n^2log))
    我们对每个数的权值排序,那么更改操作变成了(O(nlog))

    然后我们用线段树维护前缀和就好了。

    CF1539F Strange Array
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define ll long long
    #define N 200005
    
    ll n;
    ll num[N];
    
    struct P{int v,to;}e[N];
    
    bool operator < (P a,P b){
    	return a.v < b.v;
    }
    
    struct Q{ll mx,mn,tag,s;Q(){mx = 0;mn = 0;tag = 0;}}t[N << 1];//维护前缀和,支持区间加,区间min,区间max 
    
    #define l(x) (x << 1)
    #define r(x) (x << 1 | 1)
    #define mid ((l + r) >> 1)
    
    inline void pushdown(int u){
    	t[l(u)].mn += t[u].tag;
    	t[r(u)].mn += t[u].tag;
    	t[l(u)].mx += t[u].tag;
    	t[r(u)].mx += t[u].tag;
    	t[l(u)].tag += t[u].tag;
    	t[r(u)].tag += t[u].tag;
    	t[u].tag = 0;
    } 
    
    inline void up(int u){
    	t[u].mx = std::max(t[l(u)].mx,t[r(u)].mx);
    	t[u].mn = std::min(t[l(u)].mn,t[r(u)].mn);
    }
    
    ll l = 1;
    
    inline void change(int u,int l,int r,int tl,int tr,int p){
    	pushdown(u);
    	if(tl <= l && r <= tr){
    		t[u].mx += p;
    		t[u].mn += p;
    		t[u].tag += p;
    //		std::cout<<u<<"mx:"<<t[u].mx<<"mi:"<<t[u].mn<<" "<<l<<" "<<r<<" "<<tl<<" "<<tr<<" "<<p<<std::endl; 
    		return;
    	}
    	if(tl <= mid)
    	change(l(u),l,mid,tl,tr,p);
    	if(tr > mid)
    	change(r(u),mid + 1,r,tl,tr,p);
    	up(u);
    //	std::cout<<u<<"mx:"<<t[u].mx<<"mi:"<<t[u].mn<<" "<<l<<" "<<r<<" "<<tl<<" "<<tr<<" "<<p<<std::endl; 	
    } 
    
    inline ll qx(int u,int l,int r,int tl,int tr){
    	if(tr == 0)
    	return 0;
    	pushdown(u);
    	ll ans = -0x3f3f3f3f;
    	if(tl <= l && r <= tr)
    	return t[u].mx;
    	if(tl <= mid)
    	ans = std::max(ans,qx(l(u),l,mid,tl,tr));
    	if(tr > mid)
    	ans = std::max(ans,qx(r(u),mid + 1,r,tl,tr));
    	return ans; 
    }
    
    inline ll qi(int u,int l,int r,int tl,int tr){
    //	std::cout<<u<<" "<<t[u].mn<<" "<<l<<" "<<r<<" "<<tl<<" "<<tr<<std::endl; 
    	if(tr == 0)
    	return 0;
    	pushdown(u);
    	ll ans = 0x3f3f3f3f;
    	if(tl <= l && r <= tr)
    	return t[u].mn;
    	if(tl <= mid)
    	ans = std::min(ans,qi(l(u),l,mid,tl,tr));
    	if(tr > mid)
    	ans = std::min(ans,qi(r(u),mid + 1,r,tl,tr));
    	return ans; 
    }
    
    ll f[N],fa[N];
    
    int main(){
    	scanf("%lld",&n);
    	for(int i = 1;i <= n;++i)
    	scanf("%lld",&num[i]);
    	for(int i = 1;i <= n;++i)
    	e[i].v = num[i],e[i].to = i;
    	for(int i = 1;i <= n;++i)
    	change(1,1,n,i,n,1);
    	std::sort(e + 1,e + n + 1);
    	for(int i = 1;i <= n;++i){
    		ll now = e[i].to;
    		std::cout<<e[i].v<<" "<<e[i].to<<":"<<std::endl;
    		change(1,1,n,e[i].to,n,-1);
    		while(e[l].v <= e[i].v && l < i){
    //			std::cout<<l<<" "<<std::endl;
    			change(1,1,n,e[l].to,n,-2);
    			l ++ ;
    		}
    		l = i + 1;
    		while(e[l].v == e[i].v){
    			change(1,1,n,e[l].to,n,-2)
    			++l;
    			std::cout<<l<<std::endl;
    		}
    		l -- ;
    //		std::cout<<qx(1,1,n,now,n)<<" "<<std::min(qi(1,1,n,1,now - 1),(ll)0)<<std::endl;
    //		std::cout<<qi(1,1,n,now,n)<<" "<<std::max(qx(1,1,n,1,now - 1),(ll)0)<<std::endl;
    		ll ans = std::max((std::abs(qx(1,1,n,now,n) - std::min(qi(1,1,n,1,now - 1),(ll)0)) + 1),std::abs(qi(1,1,n,now,n) - std::max(qx(1,1,n,1,now - 1),(ll)0)));
    		f[now] = ans / 2;
    		change(1,1,n,e[i].to,n,1);
    		while(l > i){
    			change(1,1,n,e[l].to,n,2);
    			
    		} 		
    	}
    	for(int i = 1;i <= n;++i)
    	std::cout<<f[i]<<" ";
    }
    
    
  • 相关阅读:
    hdu5014——构造打表找规律
    HDU5124,线段树加离散化
    hdu 3400-三分套三分
    三分法——凸函数求极值问题
    Zoj 3811并查集
    iOS更新之DFU模式和恢复模式
    获取安卓系统版本
    (转)25个增强iOS应用程序性能的提示和技巧--高级篇
    (转)25个增强iOS应用程序性能的提示和技巧--中级篇
    (转)25个增强iOS应用程序性能的提示和技巧--初级篇
  • 原文地址:https://www.cnblogs.com/dixiao/p/14958140.html
Copyright © 2011-2022 走看看