zoukankan      html  css  js  c++  java
  • AtCoder acl1_d

    这是个挺平凡的 DS 题感觉。不知道为啥有 2800?

    考虑对于一个区间,先算出最大的 (|s|)。那么贪心地,显然可以从 (l) 开始往后,每次找到最左边一个 keep 住 distance 的地方跳过去直到到 (r) 右边为止。

    然后发现,(s) 中最右边一个位置一直到 (r) 都是可以当作 (s) 的最后一个的,也即最后一位的取值范围是一个区间。然后考虑倒数第二个位置的取值范围,左端点显然是原来的,右端点基于贪心是上一个区间的右端点往左跳。以此类推可以算出每个位置的取值范围。

    稍微想想,每个区间显然不可能有 (k) 个,这说明区间们不相交;然后显然的,右端点就是把之前找左端点的那个过程反过来,从 (r) 往左跳,它们得出的个数显然都是最大的 (|s|),相等,于是左端点和右端点数量匹配。这两点证明了上面那个的合理性。

    然后答案就是所有区间的个数和。那就是 (sum(r_i-l_i+1)),拆开来是 (sum r_i+sum(-l_i+1))。由于左端点和右端点的计算是独立的,于是可以分别计算。这个倍增随便搞搞就完事了。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200000,LOG_N=20;
    int n,m,qu;
    int a[N+1];
    int rit[N+1],lft[N+1];
    int rit_to[N+1][LOG_N],rit_sum[N+1][LOG_N],lft_to[N+1][LOG_N],lft_sum[N+1][LOG_N];
    int main(){
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)scanf("%d",a+i);
    	int now=1;
    	for(int i=1;i<=n;i++){
    		while(now<=n&&a[now]-a[i]<m)now++;
    		rit[i]=now;
    	}
    	rit[n+1]=n+1;
    	for(int i=n+1;i;i--){
    		rit_to[i][0]=rit[i],rit_sum[i][0]=-rit[i]+1;
    		for(int j=1;j<LOG_N;j++)
    			rit_to[i][j]=rit_to[rit_to[i][j-1]][j-1],
    			rit_sum[i][j]=rit_sum[i][j-1]+rit_sum[rit_to[i][j-1]][j-1];
    	}
    	now=n;
    	for(int i=n;i;i--){
    		while(now&&a[i]-a[now]<m)now--;
    		lft[i]=now;
    	}
    	lft[0]=0;
    	for(int i=0;i<=n;i++){
    		lft_to[i][0]=lft[i],lft_sum[i][0]=lft[i];
    		for(int j=1;j<LOG_N;j++)
    			lft_to[i][j]=lft_to[lft_to[i][j-1]][j-1],
    			lft_sum[i][j]=lft_sum[i][j-1]+lft_sum[lft_to[i][j-1]][j-1];
    	}
    	cin>>qu;
    	while(qu--){
    		int l,r;
    		scanf("%d%d",&l,&r);
    		int ans=0;
    		now=l;
    		ans+=-now+1;
    		for(int i=LOG_N-1;~i;i--)if(rit_to[now][i]<=r)ans+=rit_sum[now][i],now=rit_to[now][i];
    		now=r;
    		ans+=now;
    		for(int i=LOG_N-1;~i;i--)if(lft_to[now][i]>=l)ans+=lft_sum[now][i],now=lft_to[now][i];
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    珍爱生命,远离抄袭!
  • 相关阅读:
    AD域渗透测试笔记
    ctf之WEB练习一
    CTF之crpto练习三
    ctf之WEB练习二
    ctf之WEB练习三
    [转]Ant学习笔记——自己构建Ant编译环境
    [转]【NoSQL】NoSQL入门级资料整理(CAP原理、最终一致性)
    啥叫异步调用
    C++中虚函数的作用是什么?它应该怎么用呢?
    [转]Thrift连接池实现
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/AtCoder-acl1-d.html
Copyright © 2011-2022 走看看