codeforces 232D Fence
John Doe has a crooked fence, consisting of n rectangular planks, lined up from the left to the right: the plank that goes i-th (1 ≤ i ≤ n)(from left to right) has width 1 and height hi. We will assume that the plank that goes i-th (1 ≤ i ≤ n) (from left to right) has index i.
A piece of the fence from l to r (1 ≤ l ≤ r ≤ n) is a sequence of planks of wood with indices from l to r inclusive, that is, planks with indices l, l + 1, ..., r. The width of the piece of the fence from l to r is value r - l + 1.
Two pieces of the fence from l1 to r1 and from l2 to r2 are called matching, if the following conditions hold:
- the pieces do not intersect, that is, there isn't a single plank, such that it occurs in both pieces of the fence;
- the pieces are of the same width;
- for all i (0 ≤ i ≤ r1 - l1) the following condition holds: hl1 + i + hl2 + i = hl1 + hl2.
John chose a few pieces of the fence and now wants to know how many distinct matching pieces are for each of them. Two pieces of the fence are distinct if there is a plank, which belongs to one of them and does not belong to the other one.
The first line contains integer n (1 ≤ n ≤ 105) — the number of wood planks in the fence. The second line contains n space-separated integers h1, h2, ..., hn (1 ≤ hi ≤ 109) — the heights of fence planks.
The third line contains integer q (1 ≤ q ≤ 105) — the number of queries. Next q lines contain two space-separated integers li and ri(1 ≤ li ≤ ri ≤ n) — the boundaries of the i-th piece of the fence.
For each query on a single line print a single integer — the number of pieces of the fence that match the given one. Print the answers to the queries in the order, in which the queries are given in the input.
10
1 2 2 1 100 99 99 100 100 100
6
1 4
1 2
3 4
1 5
9 10
10 10
1
2
2
0
2
9 题解:http://tieba.baidu.com/p/2114943791?pid=28521015525&see_lz=1
code:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 200005
using namespace std;
char ch;
int n,q,N,m,l,r,h[maxn],d[maxn],s[maxn],st[][maxn];
int SA[maxn],rank[maxn],t1[maxn],t2[maxn],height[maxn],sum[maxn];
struct DATA{
int v,id;
}list[maxn];
bool cmp(DATA a,DATA b){
if (a.v!=b.v) return a.v<b.v;
return a.id<b.id;
}
struct seg{
int tot,son[maxn*][],cnt[maxn*];
void init(){tot=N;}
void insert(int k,int p,int l,int r,int x){
if (l==r){cnt[k]=cnt[p]+;return;}
int m=(l+r)>>;
if (x<=m){
cnt[k]=cnt[p]+,son[k][]=++tot,son[k][]=son[p][];
insert(son[k][],son[p][],l,m,x);
}
else{
cnt[k]=cnt[p]+,son[k][]=son[p][],son[k][]=++tot;
insert(son[k][],son[p][],m+,r,x);
}
}
int query(int k,int l,int r,int x,int y){
if (!k||x>y) return ;
if (l==x&&r==y) return cnt[k];
int m=(l+r)>>;
if (y<=m) return query(son[k][],l,m,x,y);
else if (x<=m) return query(son[k][],l,m,x,m)+query(son[k][],m+,r,m+,y);
else return query(son[k][],m+,r,x,y);
}
int query(int l,int r,int x,int y){return query(r,,N,x,y)-query(l-,,N,x,y);}
}T;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
void get_SA(){
for (int i=;i<=N;i++) list[i]=(DATA){s[i],i};
sort(list+,list+N+,cmp);
for (int i=;i<=N;i++) SA[i]=list[i].id;
int *x=t1,*y=t2,tot=;
x[SA[]]=m=;
for (int i=;i<=N;i++){
if (s[SA[i]]!=s[SA[i-]]) m++;
x[SA[i]]=m;
}
for (int len=;tot<N;len<<=,m=tot){
tot=;
for (int i=N-len+;i<=N;i++) y[++tot]=i;
for (int i=;i<=N;i++) if (SA[i]>len) y[++tot]=SA[i]-len;
for (int i=;i<=m;i++) sum[i]=;
for (int i=;i<=N;i++) sum[x[y[i]]]++;
for (int i=;i<=m;i++) sum[i]+=sum[i-];
for (int i=N;i>=;i--) SA[sum[x[y[i]]]--]=y[i];
swap(x,y),x[SA[]]=tot=;
for (int i=;i<=N;i++){
if (y[SA[i]]!=y[SA[i-]]||y[SA[i]+len]!=y[SA[i-]+len]) tot++;
x[SA[i]]=tot;
}
}
for (int i=;i<=N;i++) rank[i]=x[i];
}
void get_height(){
for (int i=,j=;i<=N;i++){
if (rank[i]==) continue;
while (s[i+j]==s[SA[rank[i]-]+j]) j++;
height[rank[i]]=j;
if (j>) j--;
}
}
void prepare(){
for (int i=;i<=N;i++) st[][i]=height[i];
for (int i=;i<=;i++)
for (int j=;j<=N;j++){
st[i][j]=st[i-][j];
if (j+(<<(i-))<=N) st[i][j]=min(st[i][j],st[i-][j+(<<(i-))]);
}
T.init();
for (int i=;i<=N;i++) T.insert(i,i-,,N,SA[i]);
}
int calc(int l,int r){
if (l>r) swap(l,r);
int t=; l++;
if (l==r) return height[r];
for (;l+(<<t)<r;t++);
if (l+(<<t)>r) t--;
return min(st[t][l],st[t][r-(<<t)+]);
}
int find(int s,int x,int op){
int l,r,m;
if (op) l=s,r=N;else l=,r=s;
while (l!=r){
m=(l+r)>>;
if (op) m++;
if (calc(m,s)<x){
if (op) r=m-;
else l=m+;
}
else{
if (op) l=m;
else r=m;
}
}
return l;
}
void query(int l,int r){
int x=find(rank[l],r-l,),y=find(rank[l],r-l,);
printf("%d\n",T.query(x,y,n+,n+(l-)-(r-l))+T.query(x,y,n+(r+),N));
}
int main(){
read(n);
for (int i=;i<=n;i++) read(h[i]);
for (int i=;i<n;i++) d[i]=h[i+]-h[i];
for (int i=;i<n;i++) s[i]=d[i];
s[n]=;
for (int i=;i<n;i++) s[n+i]=-d[i];
N=(n<<)-;
get_SA(),get_height(),prepare();
for (read(q);q;q--){
read(l),read(r);
if (l==r) printf("%d\n",n-);
else query(l,r);
}
return ;
}
codeforces 232D Fence的更多相关文章
- codeforces 448CPainting Fence
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/y990041769/article/details/37935237 题目:codeforces 4 ...
- Fence(codeforces 232D)
题意: 对于给定的a[1..n],定义区间[s,t]和[x,y]"匹配"当且仅当下列条件同时满足:1. t-s=y-x,即长度相同.3. t<x或s>y,即两区间没有交 ...
- CodeForces 363B Fence
Fence Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ...
- codeforces B.Fence 解题报告
题目链接:http://codeforces.com/problemset/problem/363/B 题目意思:给定整数n和k,需要从n个数中找出连续的k个数之和最小,输出这连续的k个数中的第一个数 ...
- Codeforces 659G Fence Divercity dp
Fence Divercity 我们设a[ i ] 为第 i 个围栏被切的最靠下的位置, 我们发现a[ i ] 的最大取值有一下信息: 如果从i - 1过来并在 i 结束a[ i ] = min(h ...
- codeforces 349B Color the Fence 贪心,思维
1.codeforces 349B Color the Fence 2.链接:http://codeforces.com/problemset/problem/349/B 3.总结: 刷栅栏.1 ...
- Codeforces 484E Sign on Fence(是持久的段树+二分法)
题目链接:Codeforces 484E Sign on Fence 题目大意:给定给一个序列,每一个位置有一个值,表示高度,如今有若干查询,每次查询l,r,w,表示在区间l,r中, 连续最长长度大于 ...
- CF&&CC百套计划4 Codeforces Round #276 (Div. 1) E. Sign on Fence
http://codeforces.com/contest/484/problem/E 题意: 给出n个数,查询最大的在区间[l,r]内,长为w的子区间的最小值 第i棵线段树表示>=i的数 维护 ...
- Codeforces Round #355 (Div. 2) A. Vanya and Fence 水题
A. Vanya and Fence 题目连接: http://www.codeforces.com/contest/677/problem/A Description Vanya and his f ...
随机推荐
- UVa 10256 凸包简单应用
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- I - Arbitrage
题目大意:套汇 套利是使用货币汇率的差异将一个单位的货币转换为多个相同的货币单位,例如1美元可以买0.5英镑,1英镑可以买10法郎,1法郎可以买0.21美元,然后聪明的人经过一些列兑换可以得到 1*0 ...
- select.poll,epoll的区别与应用
先讲讲同步I/O的五大模型 阻塞式I/O, 非阻塞式I/O, I/O复用,信号驱动I/O(SIGIO),异步I/O模型 而select/poll/epoll属于I/O复用模型 select函数 该函数 ...
- Node.js学习(7)----包
包是在模块的基础上更深一步的抽象,Node.js的包类似于C/C++函数库或者Java/.NET的类库.它将独立的功能封装起来用于发布.更新.依赖管理和版本控制. Node.js的包是一个目录,其中包 ...
- idea mac 快键键
alt + 花 + 左右 上一步下一步 shift + 花 + F 全文检索 花 + O 类查找 alt + 花 ...
- EntityFramework 使用Linq处理内连接(inner join)、外链接(left/right outer join)、多表查询
场景:在实际的项目中使用EntityFramework都会遇到使用Ef处理连接查询的问题,这里做一些小例子如何通过Linq语法处理内连接(inner join).外连接(left/right oute ...
- ScriptManager的使用方法
脚本管理控件(ScriptManger)是ASP.NET AJAX中很重要的控件,通过使用ScriptManger可以进行整个页面的局部更新的管理.ScriptManger用来处理页面上局部更新,同一 ...
- Android Studio学习随笔-移动动画的实现
在上一篇博客我已经讲述了三种事件的实现方法,而现在我用复用方法来实现控件的自动移动,当然要实现控件的移动,先得在activity_main.xml文件中放置一个控件,此处我放置的是一个button控件 ...
- MWEB+七牛 上传图片
MWEB+七牛 上传图片 博客之前的图片也都用的七牛,但编辑和上传分离还是很麻烦,所以一直很心水meb, 上周mweb降到¥50,感觉短期内应该不会再降了,于是果断入手,今天在和使用图床功能遇到了一些 ...
- [Codeforces 501D] - Misha and Permutations Summation
题意是给你两个长度为$n$的排列,他们分别是$n$的第$a$个和第$b$个全排列.输出$n$的第$\left(a+b \right)\textrm{mod} \, n!$个全排列. 一种很容易的想法是 ...