Today's problem, in addition to T2 feel I do not, ah, this is really "CSP" it
(Forget it, etc. I will become strong to do it again, in this Xiandiu)
decided to replenish cheat points system:
Tl: Pascal's triangle directly out several pretreatment compositions, and can be calculated. Note: Pascal's triangle and the actual composition is not one to one, but just the opposite vertical and horizontal coordinates, and note
to +1, that left one down the overall
T2 :( initially misread the title) for each
and
even string, ask directly to the lesser of the range in the number and
to
T3: playing table, note that rotate in the same configuration, but the symmetry axis of two different schemes to
T1
sol:
T2
sol:
Ideas:
1. open a stack to record the current node, if the stack is placed in a right node, then the bomb has been popping up left up to the legitimate nodes, each processing popped current section
, equivalent to merging the current block is a valid interval (this time interval is the minimum legal), to facilitate future build a tree for each valid segment
2. If the current interval is the right end of the current interval, it is already in step before being processed into a range of legal, so this point is marked as the father in front of that section of the left end point of a (now equivalent to merge these two intervals, the intersection of two legal sections must be lawful), record it that edge connected to the node point
3. If the current interval has not been a contribution and the current interval is valid range, this contribution section
4. the interrogation process, for each set of query, determines whether the method, outputs them
depth
can
#include <bits/stdc++.h>
using namespace std;
const int N=(int)2e6+5;
int n,m;
int l[N],r[N],f[N][20],dep[N],sta[N],top,fa[N],rt[N],r1,r2,p[N];
vector<int> v[N];
inline int read(){
int cnt=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c&15);c=getchar();}
return cnt*f;
}
void dfs(int u,int RT){
rt[u]=RT;
for(int i=1;i<=18;i++)f[u][i]=f[f[u][i-1]][i-1];
for(int i=0;i<v[u].size();i++){int to=v[u][i];dep[to]=dep[u]+1;f[to][0]=u;dfs(to,RT);}
}
int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=18;i>=0;i--)
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
if(x==y) return x;
for(int i=18;i>=0;i--)
if(f[x][i]^f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
int main(){
n=read(),m=read();
for(int i=1;i<=(n<<1);i++)p[i]=read();
for(int i=1;i<=(n<<1);i++){
l[i]=min(i,p[i]);r[i]=max(i,p[i]);
while(top&&l[i]<=sta[top]){
int x=sta[top--];
l[i]=min(l[i],l[x]);r[i]=max(r[i],r[x]);
}sta[++top]=i;
}
memset(fa,-1,sizeof(fa));memset(rt,-1,sizeof(rt));
for(int i=1;i<=(n<<1);i++){if(r[i]==i){fa[i]=l[i]-1;v[fa[i]].push_back(i);}}
for(int i=0;i<=(n<<1);i++){if((!(~rt[i]))&&(v[i].size())){dep[i]=1;dfs(i,i);}}
for(int i=1;i<=m;i++){
r1=read(),r2=read();
if(r1>r2)swap(r1,r2);
if(!r1){puts("0");continue;}
if(!(~rt[r1])||!(~rt[r2])){puts("0");continue;}
if(rt[r1]^rt[r2]){puts("0");continue;}
cout<<dep[lca(r1,r2)]-1<<'\n';
}
return 0;
}