zoukankan      html  css  js  c++  java
  • BZOJ3207: 花神的嘲讽计划Ⅰ

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3207

    可持久化线段树。

    把每段数字都hash起来,然后把询问的数字段也hash起来。

    然后询问的时候做减法就可以了。

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define maxn 200500
    #define seed 419LL
    #define mm 1000000007
    #define ll unsigned long long
    using namespace std;
    struct data{ll x;int id,l,r;
    }a[maxn],q[maxn*3];
    int sum[maxn*40],ls[maxn*40],rs[maxn*40],root[maxn*3],num[maxn];
    ll c[maxn];
    int ss,cnt,n,m,k,cnt2;
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    ll get(int x){
        ll ans=0;
        rep(i,x,x+k-1) ans=ans*seed+c[i];
        return ans;
    }
    bool cmp(data a,data b){
        return a.x<b.x;
    }
    void add(int l,int r,int x,int &y,int val){
        y=++cnt2;
        sum[y]=sum[x]+1;
        if (l==r) return;
        ls[y]=ls[x]; rs[y]=rs[x];
        int mid=(l+r)/2;
        if (val<=mid) add(l,mid,ls[x],ls[y],val);
        else add(mid+1,r,rs[x],rs[y],val);
    }
    int ask(int l,int r,int t,int val){
        if (l==r) return sum[t];
        int mid=(l+r)/2;
        if (val<=mid) return ask(l,mid,ls[t],val);
        else return ask(mid+1,r,rs[t],val);
    }
    int main(){
        n=read(); m=read(); k=read();
        rep(i,1,n) scanf("%lld",&c[i]);    
        rep(i,1,n-k+1) 
            a[i].id=i,a[i].x=get(i); 
        cnt=n-k+1;
        rep(i,1,m){
            q[i].l=read()-1; q[i].r=read()-k+1;
            rep(j,1,k) scanf("%lld",&c[j]);
            cnt++;
            a[cnt].id=cnt; a[cnt].x=get(1);
        }
        sort(a+1,a+1+cnt,cmp);
        ss=1; num[a[1].id]=1;
        rep(i,2,cnt){
            if (a[i].x!=a[i-1].x) ss++;
            num[a[i].id]=ss;
        }
        rep(i,1,n-k+1) add(1,ss,root[i-1],root[i],num[i]);
        rep(i,1,m){
            if (ask(1,ss,root[q[i].r],num[i+n-k+1])-ask(1,ss,root[q[i].l],num[i+n-k+1])>0) puts("No");
            else puts("Yes");
        }
        return 0;
    }
  • 相关阅读:
    Word如何去水印
    计算机二级公共基础知识 #02
    计算机二级公共基础知识 #01
    Linux常用快捷键
    计算机二级C语言概述 #00
    信管专业的同学都进来看一看叭~~~~~
    Python--Hanoi塔问题
    MATLAB——实验一:查看图像的RGB值
    Python课 #06号作业
    Python课 #05号作业
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5064685.html
Copyright © 2011-2022 走看看