zoukankan      html  css  js  c++  java
  • CF1172F Nauuo and Bug 题解

    Codeforces
    Luogu

    Description.

    定义函数 (f(x))return x<p?x:x-p
    给定长度为 (n(nle 10^6)) 的数列 (a_i(a_iin[-10^9,10^9])),有 (m(mle 2 imes 10^5)) 次询问。
    每次询问给定一个区间,初始 (ans=0),每次 (ansleftarrow f(ans+a_i)),问从左到右遍历后 (ans) 的答案。

    Solution.

    相当于你有一个前缀和序列,有一条线,初始在 (p),每次撞到这条线线就增高 (p)
    问最后线的位置。
    然额还是很难做。

    相当于每个位置是一个机器,吞进去一个数,吐出来一个数。
    其实是一个分段函数,如果吞进去的数 (in[-infty,p-a_i]) 就不会 (-p) 否则就会。
    可以考虑用线段树维护。

    一个区间的分段函数段数是区间长度的,同时线段树区间总长度是 (O(nlog n)) 的。
    然后每次 (O(len)) 双指针合并就行了。

    Coding.

    点击查看代码
    //Coded by Kamiyama_Shiki on 2021.11.09 {{{
    //是啊……你就是那只鬼了……所以被你碰到以后,就轮到我变成鬼了
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    const int N=1000005;int n,q;ll p,a[N];
    struct segm{vector<ll>v;ll sm;int ln;}T[N<<2];
    inline void pushup(int x)
    {
    	int ls=x<<1,rs=x<<1|1;T[x].sm=T[ls].sm+T[rs].sm;
    	T[x].v.resize(T[x].ln+2),T[x].v[0]=-1e18;
    	for(int i=1;i<=T[x].ln+1;i++) T[x].v[i]=1e18;
    	for(int il=0,ir=0;il<=T[ls].ln;il++)
    	{
    		if(ir>T[rs].ln) ir--;
    		for(;ir<=T[rs].ln;ir++)
    		{
    			ll nw=T[rs].v[ir]+il*p-T[ls].sm;
    			if(T[ls].v[il+1]-1-il*p+T[ls].sm<T[rs].v[ir]) {ir?ir--:0;break;}
    			T[x].v[il+ir]=min(T[x].v[il+ir],max(T[ls].v[il],nw));
    		}
    	}
    }
    inline void build(int x,int l,int r)
    {
    	T[x].ln=r-l+1;if(l^r) build(x<<1,l,(l+r)>>1),build(x<<1|1,((l+r)>>1)+1,r),pushup(x);
    	else T[x].sm=a[l],T[x].v.resize(3),T[x].v[0]=-1e18,T[x].v[1]=p-a[l],T[x].v[2]=1e18;
    }
    inline int fndps(vector<ll>&v,ll w) {return upper_bound(v.begin(),v.end(),w)-v.begin()-1;}
    inline ll query(int x,int l,int r,int dl,int dr,ll dc)
    {
    	int md=(l+r)>>1;if(dl<=l&&r<=dr) return dc+T[x].sm-p*fndps(T[x].v,dc);
    	if(dr<=md) return query(x<<1,l,md,dl,dr,dc);
    	else if(dl>md) return query(x<<1|1,md+1,r,dl,dr,dc);
    	else return query(x<<1|1,md+1,r,dl,dr,query(x<<1,l,md,dl,dr,dc));
    }
    int main()
    {
    	read(n,q,p);for(int i=1;i<=n;i++) read(a[i]);
    	build(1,1,n);for(int l,r;q--;) read(l,r),printf("%lld
    ",query(1,1,n,l,r,0));
    	return 0;
    }
    
  • 相关阅读:
    bzoj1644 [Usaco2007 Oct]Obstacle Course 障碍训练课
    bzoj1640 [Usaco2007 Nov]Best Cow Line 队列变换
    bzoj1639 [Usaco2007 Mar]Monthly Expense 月度开支
    bzoj1637 [Usaco2007 Mar]Balanced Lineup
    bzoj1641 [Usaco2007 Nov]Cow Hurdles 奶牛跨栏
    bzoj1635 [Usaco2007 Jan]Tallest Cow 最高的牛
    bzoj1638 [Usaco2007 Mar]Cow Traffic 奶牛交通
    bzoj3407 [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题
    bzoj1631 [Usaco2007 Feb]Cow Party
    bzoj1632 [Usaco2007 Feb]Lilypad Pond
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15531091.html
Copyright © 2011-2022 走看看