题意:

对于给定的a[1..n],定义区间[s,t]和[x,y]"匹配"当且仅当下列条件同时满足:
1. t-s=y-x,即长度相同。
3. t<x或s>y,即两区间没有交。
2. 对任0<=i<=t-s,有a[s]+a[x]=a[s+i]+a[x+i]。
现给出a[1..n]和Q个询问(x,y),求与[x,y]匹配的区间的个数。

/*
写了n个小时,还没有调出来,Orz...
代码量倒是不大,但是细节巨多,已经弃疗了。。。 先差分一下, 然后题目就变成了,也就是这段区间取相反数之后可以与原区间匹配。
设当前询问为(x,y),把整个串取相反数,再复制到后面,用后缀数组向上向下二分出可行区间。
然后要求不可重叠,就是求rank在(l,r)中有多少串的位置在一个区间内,用主席树搞一搞。
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 200010
using namespace std;
int id[N],a[N],b[N],s[N],t1[N],t2[N],c[N],sa[N],rank[N],height[N],n;
int lg2[N],st[N][],sum[N*],son[N*][],root[N],cnt;
struct node{
int x,num;
bool operator<(const node&s1)const{
if(x==s1.x) return num<s1.num;
return x<s1.x;
}
}r[N];
bool cmp(int *y,int a,int b,int k){
int a1=y[a],b1=y[b];
int a2=a+k<=n?y[a+k]:-;
int b2=b+k<=n?y[b+k]:-;
return a1==b1&&a2==b2;
}
void DA(){
int *x=t1,*y=t2,m=;
for(int i=;i<=n;i++) r[i]=(node){s[i],i};
sort(r+,r+n+);
for(int i=;i<=n;i++) sa[i]=r[i].num;
x[sa[]]=;
for(int i=;i<=n;i++) x[sa[i]]=r[i].x==r[i-].x?m:++m;
for(int k=,p=;k<=n;k*=,m=p,p=){
for(int i=n-k+;i<=n;i++) y[++p]=i;
for(int i=;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;
for(int i=;i<=m;i++) c[i]=;
for(int i=;i<=n;i++) c[x[y[i]]]++;
for(int i=;i<=m;i++) c[i]+=c[i-];
for(int i=n;i;i--) sa[c[x[y[i]]]--]=y[i];
swap(x,y);p=;x[sa[]]=;
for(int i=;i<=n;i++)
if(cmp(y,sa[i-],sa[i],k)) x[sa[i]]=p;
else x[sa[i]]=++p;
if(p>=n) break;
}
}
void geth(){
for(int i=;i<=n;i++) rank[sa[i]]=i;
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--;
}
for(int i=;i<=n;i++) lg2[i]=lg2[i>>]+;
for(int i=;i<=n;i++) st[i][]=height[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)
st[i][j]=min(st[i][j-],st[i+(<<j-)][j-]);
}
void insert(int &k,int last,int l,int r,int pos){
k=++cnt;
son[k][]=son[last][];
son[k][]=son[last][];
sum[k]=sum[last]+;
if(l==r) return;
int mid=l+r>>;
if(pos<=mid) insert(son[k][],son[last][],l,mid,pos);
else insert(son[k][],son[last][],mid+,r,pos);
}
int query(int k,int l,int r,int x,int y){
if(l>=x&&r<=y) return sum[k];
int mid=l+r>>,tot=;
if(x<=mid) tot+=query(son[k][],l,mid,x,y);
if(y>mid) tot+=query(son[k][],mid+,r,x,y);
return tot;
}
int querymn(int x,int y){
int k=lg2[y-x+];
return min(st[x][k],st[y-(<<k)+][k]);
}
int work(int x,int y){
int pos=rank[x],l=,r=pos,tmp1=pos,tmp2=pos;
while(l<r-){
int mid=l+r>>;
if(querymn(mid+,pos)>=y-x+) r=mid,tmp1=mid;
else l=mid;
}
l=pos,r=n+;
while(l<r-){
int mid=l+r>>;
if(querymn(pos+,mid)>=y-x+) l=mid,tmp2=mid;
else r=mid;
}
int ans1=query(root[tmp2],,n+,x+n/+,y+n/+)-query(root[tmp1-],,n+,x+n/+,y+n/+);
int ans2=query(root[tmp2],,n,,n/)-query(root[tmp1-],,n,,n/);
return tmp2-tmp1+-ans1-ans2;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<n;i++) s[i]=a[i+]-a[i],s[i+n]=-s[i];s[n]=-1e9;
n=n*-;DA();geth();
for(int i=;i<=n;i++)
insert(root[i],root[i-],,n,sa[i]);
int Q;scanf("%d",&Q);
while(Q--){
int x,y;scanf("%d%d",&x,&y);
if(x==y){
printf("%d\n",n/);
continue;
}
printf("%d\n",work(x,y-));
}
return ;
}

Fence(codeforces 232D)的更多相关文章

  1. 【CF484E】Sign on Fence(主席树)

    [CF484E]Sign on Fence(主席树) 题面 懒得贴CF了,你们自己都找得到 洛谷 题解 这不就是[TJOI&HEOI 排序]那题的套路吗... 二分一个答案,把大于答案的都变成 ...

  2. (CodeForces - 5C)Longest Regular Bracket Sequence(dp+栈)(最长连续括号模板)

    (CodeForces - 5C)Longest Regular Bracket Sequence time limit per test:2 seconds memory limit per tes ...

  3. Painting The Fence(贪心+优先队列)

    Painting The Fence(贪心+优先队列) 题目大意:给 m 种数字,一共 n 个,从前往后填,相同的数字最多 k 个在一起,输出构造方案,没有则输出"-1". 解题思 ...

  4. Sorted Adjacent Differences(CodeForces - 1339B)【思维+贪心】

    B - Sorted Adjacent Differences(CodeForces - 1339B) 题目链接 算法 思维+贪心 时间复杂度O(nlogn) 1.这道题的题意主要就是让你对一个数组进 ...

  5. CF448C Painting Fence (分治递归)

    Codeforces Round #256 (Div. 2) C C. Painting Fence time limit per test 1 second memory limit per tes ...

  6. (CodeForces 558C) CodeForces 558C

    题目链接:http://codeforces.com/problemset/problem/558/C 题意:给出n个数,让你通过下面两种操作,把它们转换为同一个数.求最少的操作数. 1.ai = a ...

  7. SPOJ:House Fence(分治&DP)

    "Holiday is coming, holiday is coming, hurray hurray!" shouts Joke in the last day of his ...

  8. [题解]Yet Another Subarray Problem-DP 、思维(codeforces 1197D)

    题目链接:https://codeforces.com/problemset/problem/1197/D 题意: 给你一个序列,求一个子序列 a[l]~a[r] 使得该子序列的 sum(l,r)-k ...

  9. 【Codeforces】【图论】【数量】【哈密顿路径】Fake bullions (CodeForces - 804F)

    题意 有n个黑帮(gang),每个黑帮有siz[i]个人,黑帮与黑帮之间有有向边,并形成了一个竞赛完全图(即去除方向后正好为一个无向完全图).在很多年前,有一些人参与了一次大型抢劫,参与抢劫的人都获得 ...

随机推荐

  1. vue 服务代理 调用第三方api

    项目中前期需要调用第三方API来获取汇率.因为直接调用会有跨域的问题,所以使用来服务代理. 在config配置代理可以这样写: 而调用接口就可以这样写: 坑:配置完成后一直报500,开始怀疑人生.最后 ...

  2. ios 导航视图控制器 跳转

    import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoa ...

  3. 两种方法实现text输入框中“请输入关键字”的提醒

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. dynamic routing between captual

    对于人脑 决策树形式 对于CNN 层级与层级间的传递 人在识别物体的时候会进行坐标框架的设置 CNN无法识别,只能通过大量训练 胶囊 :一个神经元集合,有一个活动的向量,来表示物体的各类信息,向量的长 ...

  5. 火狐IE event和target的兼容

    一.event对象 IE 中可以直接使用 window.event 对象,而 FF 中则不可以,解决方法之一如下: var theEvent = window.event || arguments.c ...

  6. JZOJ 1265. Round Numbers

    1265. Round Numbers(rndnum.pas/c/cpp) (File IO): input:rndnum.in output:rndnum.out Time Limits: 1000 ...

  7. Neon Lights in Hong Kong【香港霓虹灯】

    Neon Lights in Hong Kong Neon is to Hong Kong as red phone booths are to London and fog is to San Fr ...

  8. Leetcode 515. 在每个树行中找最大值

    题目链接 https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/description/ 题目描述 您需要在二叉树的 ...

  9. 工具类commons-io的Tailer用来监控文件

    一.前言:在Linux下有使用tail命令 在Commons-io中也提供这种方法 二.他采用的是线程方式来监控文件内容的变化 1.Tailer类(采用线程的方式进行文件的内容变法) 2.Tailer ...

  10. Spring表达式语言:SpEL

    1.Spring表达式语言(简称:SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言. 2.语法类似于EL:SpEL使用#{...}作为定界符,所有在大括号内的字符都被认为是SpEL. 3 ...