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.

Input

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.

Output

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.

Sample test(s)

input

101 2 2 1 100 99 99 100 100 10061 41 23 41 59 1010 10

output

122029

题解:http://tieba.baidu.com/p/2114943791?pid=28521015525&see_lz=1code:
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #define maxn 200005
  7 using namespace std;
  8 char ch;
  9 int n,q,N,m,l,r,h[maxn],d[maxn],s[maxn],st[18][maxn];
 10 int SA[maxn],rank[maxn],t1[maxn],t2[maxn],height[maxn],sum[maxn];
 11 struct DATA{
 12     int v,id;
 13 }list[maxn];
 14 bool cmp(DATA a,DATA b){
 15     if (a.v!=b.v) return a.v<b.v;
 16     return a.id<b.id;
 17 }
 18 struct seg{
 19     int tot,son[maxn*80][2],cnt[maxn*80];
 20     void init(){tot=N;}
 21     void insert(int k,int p,int l,int r,int x){
 22         if (l==r){cnt[k]=cnt[p]+1;return;}
 23         int m=(l+r)>>1;
 24         if (x<=m){
 25             cnt[k]=cnt[p]+1,son[k][0]=++tot,son[k][1]=son[p][1];
 26             insert(son[k][0],son[p][0],l,m,x);
 27         }
 28         else{
 29             cnt[k]=cnt[p]+1,son[k][0]=son[p][0],son[k][1]=++tot;
 30             insert(son[k][1],son[p][1],m+1,r,x);
 31         }
 32     }
 33     int query(int k,int l,int r,int x,int y){
 34         if (!k||x>y) return 0;
 35         if (l==x&&r==y) return cnt[k];
 36         int m=(l+r)>>1;
 37         if (y<=m) return query(son[k][0],l,m,x,y);
 38         else if (x<=m) return query(son[k][0],l,m,x,m)+query(son[k][1],m+1,r,m+1,y);
 39         else return query(son[k][1],m+1,r,x,y);
 40     }
 41     int query(int l,int r,int x,int y){return query(r,1,N,x,y)-query(l-1,1,N,x,y);}
 42 }T;
 43 bool ok;
 44 void read(int &x){
 45     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1;
 46     for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());
 47     if (ok) x=-x;
 48 }
 49 void get_SA(){
 50     for (int i=1;i<=N;i++) list[i]=(DATA){s[i],i};
 51     sort(list+1,list+N+1,cmp);
 52     for (int i=1;i<=N;i++) SA[i]=list[i].id;
 53     int *x=t1,*y=t2,tot=0;
 54     x[SA[1]]=m=1;
 55     for (int i=2;i<=N;i++){
 56         if (s[SA[i]]!=s[SA[i-1]]) m++;
 57         x[SA[i]]=m;
 58     }
 59     for (int len=1;tot<N;len<<=1,m=tot){
 60         tot=0;
 61         for (int i=N-len+1;i<=N;i++) y[++tot]=i;
 62         for (int i=1;i<=N;i++) if (SA[i]>len) y[++tot]=SA[i]-len;
 63         for (int i=1;i<=m;i++) sum[i]=0;
 64         for (int i=1;i<=N;i++) sum[x[y[i]]]++;
 65         for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
 66         for (int i=N;i>=1;i--) SA[sum[x[y[i]]]--]=y[i];
 67         swap(x,y),x[SA[1]]=tot=1;
 68         for (int i=2;i<=N;i++){
 69             if (y[SA[i]]!=y[SA[i-1]]||y[SA[i]+len]!=y[SA[i-1]+len]) tot++;
 70             x[SA[i]]=tot;
 71         }
 72     }
 73     for (int i=1;i<=N;i++) rank[i]=x[i];
 74 }
 75 void get_height(){
 76     for (int i=1,j=0;i<=N;i++){
 77         if (rank[i]==1) continue;
 78         while (s[i+j]==s[SA[rank[i]-1]+j]) j++;
 79         height[rank[i]]=j;
 80         if (j>0) j--;
 81     }
 82 }
 83 void prepare(){
 84     for (int i=1;i<=N;i++) st[0][i]=height[i];
 85     for (int i=1;i<=17;i++)
 86         for (int j=1;j<=N;j++){
 87             st[i][j]=st[i-1][j];
 88             if (j+(1<<(i-1))<=N) st[i][j]=min(st[i][j],st[i-1][j+(1<<(i-1))]);
 89         }
 90     T.init();
 91     for (int i=1;i<=N;i++) T.insert(i,i-1,1,N,SA[i]);
 92 }
 93 int calc(int l,int r){
 94     if (l>r) swap(l,r);
 95     int t=0; l++;
 96     if (l==r) return height[r];
 97     for (;l+(1<<t)<r;t++);
 98     if (l+(1<<t)>r) t--;
 99     return min(st[t][l],st[t][r-(1<<t)+1]);
100 }
101 int find(int s,int x,int op){
102     int l,r,m;
103     if (op) l=s,r=N;else l=1,r=s;
104     while (l!=r){
105         m=(l+r)>>1;
106         if (op) m++;
107         if (calc(m,s)<x){
108             if (op) r=m-1;
109             else l=m+1;
110         }
111         else{
112             if (op) l=m;
113             else r=m;
114         }
115     }
116     return l;
117 }
118 void query(int l,int r){
119     int x=find(rank[l],r-l,0),y=find(rank[l],r-l,1);
120     printf("%d\n",T.query(x,y,n+1,n+(l-1)-(r-l))+T.query(x,y,n+(r+1),N));
121 }
122 int main(){
123     read(n);
124     for (int i=1;i<=n;i++) read(h[i]);
125     for (int i=1;i<n;i++) d[i]=h[i+1]-h[i];
126     for (int i=1;i<n;i++) s[i]=d[i];
127     s[n]=1;
128     for (int i=1;i<n;i++) s[n+i]=-d[i];
129     N=(n<<1)-1;
130     get_SA(),get_height(),prepare();
131     for (read(q);q;q--){
132         read(l),read(r);
133         if (l==r) printf("%d\n",n-1);
134         else query(l,r);
135     }
136     return 0;
137 }
时间: 2024-12-15 01:35:28

codeforces 232D Fence的相关文章

codeforces 448CPainting Fence

题目:codeforces 448CPainting Fence 题意:n个1* a [ i ] 的木板,把他们立起来,变成每个木板宽为1长为 a [ i ] 的栅栏,现在要给栅栏刷漆,刷子宽1,每一刷子可以刷任意长,现在让你求最少需要多少刷子? 分析:题目看似没有头绪,仔细分析的话其实很简单 首先,我们假如每次都刷一个木板,即一竖行,那么需要n次刷完,可见这是一个ans的最大值.就是最差的情况下我这样刷最多为n刷. 其次:如果我们选择一横行的刷,而n个木板中最短的为min,那么我们可以花min

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... 代码量倒是不大,但是细节巨多,已经弃疗了... 先差分一下, 然后题目就变成了,也就是这段区

CodeForces 363B Fence

Fence Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 363B64-bit integer IO format: %I64d      Java class name: (Any) There is a fence in front of Polycarpus's home. The fence consists of n planks of

Codeforces 659G Fence Divercity dp

Fence Divercity 我们设a[ i ] 为第 i 个围栏被切的最靠下的位置, 我们发现a[ i ] 的最大取值有一下信息: 如果从i - 1过来并在 i  结束a[ i ] = min(h[ i - 1], h[ i ]) 如果从i - 1过来并延续到i + 1,   a[ i ] = min(h[ i - 1 ], h[ i ], h[ i + 1 ]) 如果从 i 开始 i 结束 a[ i ] = h[ i ] 如果从 i 开始并延续到 i + 1,   a[ i ] = min

16.05.25-16.06.10 题集

继2016.05.24续: codeforces 651B. Beautiful Paintings-简单 http://codeforces.com/problemset/problem/651/B 大意:给出一个序列,求解其任意排列中满足ai?+?1?>?ai 的元素个数最大和. 分析:理想情况下,无重复元素的0从小到大的排列,满足条件的元素个数最多,是n-1. 非理想情况下还有重复元素,只要不断提取出重复的这些元素归到另一集合再这样讨论即可. #include <iostream>

Codeforces Round #256 (Div. 2) C. Painting Fence(分治贪心)

题目链接:http://codeforces.com/problemset/problem/448/C ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

Codeforces 484E Sign on Fence(可持久化线段树+二分)

题目链接:Codeforces 484E Sign on Fence 题目大意:给定给一个序列,每个位置有一个值,表示高度,现在有若干查询,每次查询l,r,w,表示在区间l,r中, 连续最长长度大于w的最大高度为多少. 解题思路:可持久化线段树维护区间合并,前端时间碰到一题可持久化字典树,就去查了一下相关论文,大概知道了是 什么东西. 将高度按照从大到小的顺序排序,然后每次插入一个位置,线段树维护最长连续区间,因为插入是按照从大到小的顺 序,所以每次的线段树中的连续最大长度都是满足高度大于等于当

Codeforces Round #256 (Div. 2)——Painting Fence

题目连接 题意: n个木条,输入n个木条的高度,每个木条的宽度均为1.现在有长宽均为1的刷子,每次可以选择横着刷或者竖着刷,每次刷的时候不能离开木条,问将所有木条均涂色至少需要刷几次.(刷的时候可以经过已经被刷过的地方) n (1?≤?n?≤?5000),1?≤?ai(高度)?≤?109 分析: 分析一下横着和竖着的关系:假设现在已经有一个操作集合S是答案,那么集合中的操作顺序是可以改变的,即横和竖的顺序可以改变(因为可以经过已经涂色的木条),那么不妨先横着涂色.对于当前[l,r]的区间,答案不

Codeforces Round #256 (Div. 2/C)/Codeforces448C_Painting Fence(分治)

解题报告 给篱笆上色,要求步骤最少,篱笆怎么上色应该懂吧,,,刷子可以在横着和竖着刷,不能跳着刷,,, 如果是竖着刷,应当是篱笆的条数,横着刷的话,就是刷完最短木板的长度,再接着考虑没有刷的木板,,, 递归调用,,, #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define inf 999999999999999 using namespace