• 【LOJ#2019】【AHOI / HNOI2017】—影魔(线段树+扫描线)


    传送门

    发现只用考虑每个值作为最大的时候即可
    发现贡献可以看做平面上点和线段
    扫描线即可

    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    #define ll long long
    #define pb push_back
    #define cs const
    #define bg begin
    #define pii pair<int,int>
    #define fi first
    #define se second
    cs int RLEN=1<<20|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ib==ob)?EOF:*ib++;
    }
    inline char getc(){
    	char ch=gc();
    	while(!isalpha(ch))ch=gc();
    	return ch;
    }
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int N=200005;
    int n,m,p1,p2;
    struct ask{
    	int l,r,coef,id;
    	ask(int _1=0,int _2=0,int _3=0,int _4=0):l(_1),r(_2),coef(_3),id(_4){}
    };
    vector<ask> q[N];
    struct opt{
    	int l,r,val;
    	opt(int _1=0,int _2=0,int _3=0):l(_1),r(_2),val(_3){}
    };
    vector<opt> p[N];
    namespace Seg{
    	int tag[N<<2];ll s[N<<2];
    	#define lc (u<<1)
    	#define rc ((u<<1)|1)
    	#define mid ((l+r)>>1)
    	inline void pushup(int u){
    		s[u]=s[lc]+s[rc];
    	}
    	inline void pushnow(int u,int l,int r,int k){
    		tag[u]+=k,s[u]+=1ll*(r-l+1)*k;
    	}
    	inline void pushdown(int u,int l,int r){
    		if(!tag[u])return ;
    		pushnow(lc,l,mid,tag[u]);
    		pushnow(rc,mid+1,r,tag[u]);
    		tag[u]=0;
    	}
    	void update(int u,int l,int r,int st,int des,int k){
    		if(st<=l&&r<=des)return pushnow(u,l,r,k);
    		pushdown(u,l,r);
    		if(st<=mid)update(lc,l,mid,st,des,k);
    		if(mid<des)update(rc,mid+1,r,st,des,k);
    		pushup(u);
    	}
    	ll query(int u,int l,int r,int st,int des){
    		if(st<=l&&r<=des)return s[u];
    		ll res=0;pushdown(u,l,r);
    		if(st<=mid)res+=query(lc,l,mid,st,des);
    		if(mid<des)res+=query(rc,mid+1,r,st,des);
    		pushup(u);return res;
    	}
    }
    int L[N],R[N],a[N];
    int stk[N],top;
    ll ans[N];
    int main(){
    	#ifdef Stargazer
    	freopen("lx.cpp","r",stdin);
    	freopen("my.out","w",stdout);
    	#endif
    	n=read(),m=read(),p1=read(),p2=read();
    	for(int i=1;i<=n;i++)a[i]=read();a[n+1]=n+1;
    	for(int i=1;i<=n;i++){
    		while(top&&a[stk[top]]<a[i])top--;
    		L[i]=stk[top],stk[++top]=i;
    	}
    	stk[top=1]=n+1;
    	for(int i=n;i;i--){
    		while(top&&a[stk[top]]<a[i])top--;
    		R[i]=stk[top],stk[++top]=i;
    	}
    	for(int i=1;i<=n;i++){
    		int l=L[i],r=R[i];
    		if(l&&i+1<r)p[l].pb(opt(i+1,r-1,p2));
    		if(r<=n&&l+1<i)p[r].pb(opt(l+1,i-1,p2));
    		if(l)p[r].pb(opt(l,l,p1));
    	}
    	for(int i=1;i<=m;i++){
    		int l=read(),r=read();
    		q[l-1].pb(ask(l,r,-1,i));
    		q[r].pb(ask(l,r,1,i));
    		ans[i]=1ll*(r-l)*p1;
    	}
    	for(int i=1;i<=n;i++){
    		for(opt &x:p[i]){
    			Seg::update(1,1,n,x.l,x.r,x.val);
    		}
    		for(ask &x:q[i]){
    			ans[x.id]+=Seg::query(1,1,n,x.l,x.r)*x.coef;
    		}
    	}
    	for(int i=1;i<=m;i++)cout<<ans[i]<<'
    ';
    }
    
  • 相关阅读:
    关于js的语句类型运算符等
    关于flex的布局理解
    三天来都在写项目;今天开始学习了js
    12.13的学习内容
    Css多列语法笔记
    Css3关键帧动画
    codevs1085数字游戏(环形DP+划分DP )
    codevs1040统计单词个数(区间+划分型dp)
    POJ1062昂贵的聘礼
    POJ3687Labeling Balls
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328382.html
Copyright © 2020-2023  润新知