bzoj 3207

hash + 主席树

#include <bits/stdc++.h>
using namespace std;
typedef int lint;
typedef long long LL;
typedef unsigned long long ull;
const int maxn = 8000005;
const ull inf = -1;
lint a[200005];
ull H[200005];
lint rt[200005];
lint ch[maxn][2],sum[maxn];
lint cnt = 0;
void update( int x,int& y,ull val ){
    ull l = 0,r = inf;
    y = ++cnt;int temp = y;
    sum[y] = sum[x]+1;
    while(l != r){
        ull mid =  (l >>1) +(r>>1);
        if( (l&1) && (r&1) )mid++;
        int t = 0;
        if( val > mid ){
            t = 1;
            l = mid+1;
        }else r = mid-1;
        ch[y][t^1] = ch[x][t^1];
        ch[y][t]=++cnt;
        y = ch[y][t];x = ch[x][t];
        sum[y] = sum[x]+1;
    }
    y = temp;
}
bool query( int x,int y,ull val ){
    ull l = 0,r = inf;
    while(l!=r){
        ull mid = (l>>1)+(r>>1);
        if((l&1)&&(r&1)) mid++;
        int t = 0;
        if( val > mid )t = 1,l = mid+1;
        else r = mid-1;
        y = ch[y][t];x= ch[x][t];
    }
    return sum[y] - sum[x] > 0;
}
int main(){
    lint n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for( lint i = 1;i <= n;i++ )scanf("%d",&a[i]);
    for( lint i = 1;i <= n;i++ ){
        H[i] = H[i-1]*107 + a[i];
    }
    ull mm = 1;
    for( lint i = 1;i <= k;i++ ) mm *= 107;
    for( lint i = k;i <= n;i++ ){
        update( rt[i-1],rt[i],H[i] - mm*H[i-k] );
    }
    int l,r;
    for( lint i = 1;i <= m;i++ ){
        scanf("%d%d",&l,&r);
        ull v = 0;
        int x;
        for( lint j = 1;j <= k;j++ ){
            scanf("%d",&x);
            v = v*107 + x;
        }
        bool f = query( rt[l+k-2],rt[r],v );
        if(f){
            printf("No\n");
        }else{
            printf("Yes\n");
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值