## Task.1 Global warming (JZOJ 6310)

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

x=0; bool f=0; char c=getchar();
while(c<'0'||'9'<c){f|=(c=='-'); c=getchar();}
while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
x=f?-x:x;
}

const int N=200005;

int n,d,ans;
int a[N],b[N<<2],m,t[N],c[N];
int f[N],g[N];
void cmax(int &x,int y){if(x<y)x=y;}
struct segt{
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
int s[N<<3];
void clear(){memset(s,0,sizeof(s));}
void pushup(int p){s[p]=max(s[p<<1],s[p<<1|1]);}
void upd(int x,int c,int l,int r,int p){
if(l==r){cmax(s[p],c); return ;}
int mid=(l+r)>>1;
if(x<=mid)upd(x,c,lson);
else upd(x,c,rson);
pushup(p);
}
int query(int L,int R,int l,int r,int p){
if(R<L)return 0;
if(L<=l&&r<=R) return s[p];
int mid=(l+r)>>1,res=0;
if(L<=mid)res=max(res,query(L,R,lson));
if(R>mid)res=max(res,query(L,R,rson));
return res;
}
}T;

void solve(){
sort(b+1,b+m+1); m=unique(b+1,b+m+1)-b-1;
for(int i=1;i<=n;i++){
t[i]=lower_bound(b+1,b+m+1,a[i])-b;
c[i]=lower_bound(b+1,b+m+1,a[i]+d)-b;
}
for(int i=1;i<=n;i++){
f[i]=T.query(1,t[i]-1,1,m,1)+1;
T.upd(t[i],f[i],1,m,1);
}
T.clear();
for(int i=n;i;i--){
g[i]=T.query(t[i]+1,m,1,m,1)+1;
T.upd(t[i],g[i],1,m,1);
}
T.clear();
for(int i=1;i<=n;i++){
T.upd(t[i],f[i],1,m,1);
cmax(ans,g[i+1]+T.query(1,c[i+1]-1,1,m,1));
}
printf("%d\n",ans);
}

int main(){
freopen("glo.in","r",stdin);
freopen("glo.out","w",stdout);
for(int i=1;i<=n;i++){
b[++m]=a[i];
b[++m]=a[i]+d;
}
solve();
return 0;
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

x=0; char c=getchar();
while(c<'0'||'9'<c)c=getchar();
while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}

const int N=305;
const int NN=1000005;
const int M=1000000007;

int r,s,n;
int a[N][N];
int rk[2005],id[NN],cnt;
int f[2][N][2005];

int inv(int x){
int res=1,t=M-2;
while(t){
if(t&1)res=1ll*res*x%M;
x=1ll*x*x%M; t>>=1;
}return res;
}
int C(int x,int y){
int up=1,down=1;
if(y<x-y)y=x-y;
for(int i=y+1;i<=x;i++)
up=1ll*up*i%M;
if(y>x-y)y=x-y;
for(int i=1;i<=y;i++)
down=1ll*down*i%M;
return 1ll*up*inv(down)%M;
}

int main(){
freopen("mobitel.in","r",stdin);
freopen("mobitel.out","w",stdout);
n--;
for(int i=1;i<=n;i++)if(rk[cnt]!=n/i){
rk[++cnt]=n/i;
id[n/i]=cnt;
}
int t;
bool now=0,pre=1;
f[0][1][1]=1;
for(int i=1;i<=r;i++){
swap(now,pre);
memset(f[now],0,sizeof(f[now]));
for(int j=1;j<=s;j++){
t=a[i][j];
for(int k=1;k<=cnt;k++){
f[now][j][id[rk[k]/t]]=(1ll*f[now][j][id[rk[k]/t]]+1ll*f[pre][j][k]+f[now][j-1][k])%M;
}
}
}
int sum=0;
for(int i=1;i<=cnt;i++)sum=(sum+f[now][s][i])%M;
printf("%d\n",(C(r+s-2,s-1)-sum+M)%M);
return 0;
}


$q$ 组询问，第 $j$ 组询问给出一个 $k_j$，求每个子串与多少个其它的子串可称为 $k_j$ 相似。