Fence(codeforces 232D)
题意:
对于给定的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)的更多相关文章
- 【CF484E】Sign on Fence(主席树)
[CF484E]Sign on Fence(主席树) 题面 懒得贴CF了,你们自己都找得到 洛谷 题解 这不就是[TJOI&HEOI 排序]那题的套路吗... 二分一个答案,把大于答案的都变成 ...
- (CodeForces - 5C)Longest Regular Bracket Sequence(dp+栈)(最长连续括号模板)
(CodeForces - 5C)Longest Regular Bracket Sequence time limit per test:2 seconds memory limit per tes ...
- Painting The Fence(贪心+优先队列)
Painting The Fence(贪心+优先队列) 题目大意:给 m 种数字,一共 n 个,从前往后填,相同的数字最多 k 个在一起,输出构造方案,没有则输出"-1". 解题思 ...
- Sorted Adjacent Differences(CodeForces - 1339B)【思维+贪心】
B - Sorted Adjacent Differences(CodeForces - 1339B) 题目链接 算法 思维+贪心 时间复杂度O(nlogn) 1.这道题的题意主要就是让你对一个数组进 ...
- CF448C Painting Fence (分治递归)
Codeforces Round #256 (Div. 2) C C. Painting Fence time limit per test 1 second memory limit per tes ...
- (CodeForces 558C) CodeForces 558C
题目链接:http://codeforces.com/problemset/problem/558/C 题意:给出n个数,让你通过下面两种操作,把它们转换为同一个数.求最少的操作数. 1.ai = a ...
- SPOJ:House Fence(分治&DP)
"Holiday is coming, holiday is coming, hurray hurray!" shouts Joke in the last day of his ...
- [题解]Yet Another Subarray Problem-DP 、思维(codeforces 1197D)
题目链接:https://codeforces.com/problemset/problem/1197/D 题意: 给你一个序列,求一个子序列 a[l]~a[r] 使得该子序列的 sum(l,r)-k ...
- 【Codeforces】【图论】【数量】【哈密顿路径】Fake bullions (CodeForces - 804F)
题意 有n个黑帮(gang),每个黑帮有siz[i]个人,黑帮与黑帮之间有有向边,并形成了一个竞赛完全图(即去除方向后正好为一个无向完全图).在很多年前,有一些人参与了一次大型抢劫,参与抢劫的人都获得 ...
随机推荐
- vue 服务代理 调用第三方api
项目中前期需要调用第三方API来获取汇率.因为直接调用会有跨域的问题,所以使用来服务代理. 在config配置代理可以这样写: 而调用接口就可以这样写: 坑:配置完成后一直报500,开始怀疑人生.最后 ...
- ios 导航视图控制器 跳转
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoa ...
- 两种方法实现text输入框中“请输入关键字”的提醒
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- dynamic routing between captual
对于人脑 决策树形式 对于CNN 层级与层级间的传递 人在识别物体的时候会进行坐标框架的设置 CNN无法识别,只能通过大量训练 胶囊 :一个神经元集合,有一个活动的向量,来表示物体的各类信息,向量的长 ...
- 火狐IE event和target的兼容
一.event对象 IE 中可以直接使用 window.event 对象,而 FF 中则不可以,解决方法之一如下: var theEvent = window.event || arguments.c ...
- JZOJ 1265. Round Numbers
1265. Round Numbers(rndnum.pas/c/cpp) (File IO): input:rndnum.in output:rndnum.out Time Limits: 1000 ...
- 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 ...
- Leetcode 515. 在每个树行中找最大值
题目链接 https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/description/ 题目描述 您需要在二叉树的 ...
- 工具类commons-io的Tailer用来监控文件
一.前言:在Linux下有使用tail命令 在Commons-io中也提供这种方法 二.他采用的是线程方式来监控文件内容的变化 1.Tailer类(采用线程的方式进行文件的内容变法) 2.Tailer ...
- Spring表达式语言:SpEL
1.Spring表达式语言(简称:SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言. 2.语法类似于EL:SpEL使用#{...}作为定界符,所有在大括号内的字符都被认为是SpEL. 3 ...