• 【Codeforces 1172F】—Nauuo and Bug(线段树+双指针)


    传送门

    一个位置的时候
    f(x)={x+v(x<pv)x+vp  otherwise f(x)= egin{cases} x+v(x<p-v)\ x+v-p otherwise end{cases}

    这时候是一个分段一次函数
    对于x,x+1x,x+1 2个位置的函数其实是fx(fx+1(x))f_x(f_{x+1}(x))
    对于nn个位置复合起来的函数显然总段数不超过O(n)O(n)
    考虑用线段树维护这样一个复合函数
    每次合并双指针做一下就可以了

    细节有点难受

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    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;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    struct node{
    	ll l,b;
    	node(ll _l=0,ll _b=0):l(_l),b(_b){}
    };
    cs int N=1000005;
    cs ll inf=1e15;
    int n,m;
    int mod,a[N];
    #define poly vector<node>
    inline void merge(poly &res,poly a,poly b){
    	for(int i=0,j=0;i<a.size();){
    		ll vl=(a[i].l==inf?-inf:a[i].l+a[i].b),vr=(i+1==a.size()?inf:a[i+1].l-1+a[i].b);
    		while(j&&b[j].l>vl)j--;
    		while(j+1<b.size()&&b[j+1].l-1<vl)j++;
    		ll mxr=(j+1==b.size()?inf:b[j+1].l-1);
    		if(mxr<vr){
    			if(!res.size()||res.back().b!=a[i].b+b[j].b)//不判这个会MLE,虽然不是很明白为什么空间会大那么多
    			res.pb(node(a[i].l,a[i].b+b[j].b));
    			a[i].l=mxr-a[i].b+1;
    		}
    		else{
    			if(!res.size()||res.back().b!=a[i].b+b[j].b)
    			res.pb(node(a[i].l,a[i].b+b[j].b));
    			i++;
    		}
    	}
    }
    namespace Seg{
    	poly tr[N<<2];
    	inline ll calc(cs poly &a,ll x){
    		int l=0,r=(int)a.size()-1,pos=0;
    		while(l<=r){
    			int mid=(l+r)>>1;
    			if(a[mid].l<=x)l=mid+1,pos=mid;
    			else r=mid-1;
    		}
    		return x+a[pos].b;
    	}
    	#define lc (u<<1)
    	#define rc ((u<<1)|1)
    	#define mid ((l+r)>>1)
    	inline void pushup(int u){
    		merge(tr[u],tr[lc],tr[rc]);
    	}
    	void build(int u,int l,int r){
    		if(l==r){tr[u].pb(node(-inf,a[l])),tr[u].pb(node(mod-a[l],a[l]-mod));return;}
    		build(lc,l,mid),build(rc,mid+1,r);
    		pushup(u);
    	}
    	inline ll query(int u,int l,int r,int st,int des,ll v){
    		if(st<=l&&r<=des)return calc(tr[u],v);
    		if(st<=mid)v=query(lc,l,mid,st,des,v);
    		if(mid<des)v=query(rc,mid+1,r,st,des,v);
    		return v;
    	}
    }
    
    signed main(){
    	n=read(),m=read(),mod=read();
    	for(int i=1;i<=n;i++)a[i]=read();
    	Seg::build(1,1,n);
    	while(m--){
    		int l=read(),r=read();
    		cout<<Seg::query(1,1,n,l,r,0)<<'
    ';
    	}
    }
    
  • 相关阅读:
    linux ubuntu 现在显示的是ubuntu login
    stop-hbase.sh出现stopping hbasecat:/tmp/hbase-root-master.pid:No such file or directory
    hbase shell出现ERROR:Can't get master address from Zookeeper;znode data==null
    HADOOP:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
    当Hadoop 启动节点Datanode失败解决
    数据挖掘步骤
    参加kaggle比赛
    招聘
    前端简历
    js和CSS3炫酷3D相册展示
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328545.html
Copyright © 2020-2023  润新知