• BZOJ 3207 花神的嘲讽计划Ⅰ


     题意:给定一个序列,每次询问区间 [l,r] 内是否存在一个长度为K的子串.

     由于K是固定的,字符串hash再离散,然后问题转化成了询问区间[l,r]内是否存在一个要求的数.

     可持久化线段树可切,离线乱搞同样支持,可以试下可持久化01Trie.

     

     1 #include<algorithm>
     2 #include<cstdio>
     3 using namespace std;
     4 #define ll long long
     5 #define FILE "dealing"
     6 #define up(i,j,n) for(int i=j;i<=n;i++)
     7 #define db long double 
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 #define mem(a,L) memset(a,0,sizeof(int)*(L+1))
    11 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
    12 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
    13 template<class T> inline T squ(T a){return a*a;}
    14 const ll maxn=2000100+10,MAXN=200200,inf=1e9+10,limit=1e7,base=23;
    15 int read(){
    16     int x=0,f=1,ch=getchar();
    17     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    18     while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    19     return x*f;
    20 }
    21 
    22 unsigned long long hash[MAXN],k[MAXN];
    23 
    24 int n,M,K;
    25 int a[MAXN],w[MAXN],root[MAXN];
    26 struct query{
    27     int l,r;
    28     unsigned long long v;
    29 }q[MAXN];
    30 unsigned long long get(int l,int r){
    31     return hash[l]-hash[r+1]*k[r-l+1];
    32 }
    33 pair<unsigned long long,pii > t[MAXN];
    34 int val[MAXN],m;
    35 int cnt=0;
    36 int c[maxn][2],sum[maxn],Cnt=0;
    37 void updata(int o){
    38     sum[o]=sum[c[o][0]]+sum[c[o][1]];
    39 }
    40 void insert(int pre,int& o,int l,int r,int key){
    41     o=++Cnt;
    42     if(l==r){
    43         sum[o]=sum[pre]+1;
    44         return;
    45     }
    46     int mid=(l+r)>>1;
    47     if(key>mid)c[o][0]=c[pre][0],insert(c[pre][1],c[o][1],mid+1,r,key);
    48     else c[o][1]=c[pre][1],insert(c[pre][0],c[o][0],l,mid,key);
    49     updata(o);
    50 }
    51 bool query(int pre,int o,int l,int r,int key){
    52     int mid=(l+r)>>1;
    53     if(l==r||!(sum[o]-sum[pre]))return sum[o]-sum[pre];
    54     if(key>mid)return query(c[pre][1],c[o][1],mid+1,r,key);
    55     else return query(c[pre][0],c[o][0],l,mid,key);
    56 }
    57 int main(){
    58     freopen(FILE".in","r",stdin);
    59     freopen(FILE".out","w",stdout);
    60     n=read(),M=read(),K=read();
    61     up(i,1,n)a[i]=read();
    62     k[0]=1;up(i,1,n)k[i]=k[i-1]*base;
    63     for(int i=n;i>=1;i--)
    64         hash[i]=hash[i+1]*base+a[i];
    65     for(int i=1;i<=M;i++){
    66         q[i].l=read(),q[i].r=read();
    67         unsigned long long u=0;
    68         for(int j=1;j<=K;j++)w[j]=read();
    69         for(int j=K;j>=1;j--)u=u*base+w[j];
    70         q[i].v=u;
    71     }
    72     for(int i=1;i<=n-K+1;i++)
    73         t[++cnt]=make_pair(get(i,i+K-1),make_pair(i,1));
    74     for(int i=1;i<=M;i++)
    75         t[++cnt]=make_pair(q[i].v,make_pair(i,2));
    76     sort(t+1,t+cnt+1);
    77     for(int i=1;i<=cnt;i++){
    78         if(i==1||t[i].first!=t[i-1].first)m++;
    79         if(t[i].second.second==1)val[t[i].second.first]=m;
    80         else q[t[i].second.first].v=m;
    81     }
    82     for(int i=1;i<=n-K+1;i++)
    83         insert(root[i-1],root[i],1,m,val[i]);
    84     for(int i=1;i<=M;i++){
    85         if(query(root[q[i].l-1],root[q[i].r-K+1],1,m,q[i].v))printf("No
    ");
    86         else printf("Yes
    ");
    87     }
    88     return 0;
    89 }
    View Code

     

  • 相关阅读:
    【机器学习】K-means文本聚类,python
    【机器学习】K-means文本聚类,简单入门版,python
    【python】jiaba分词,停用词分享,stopwords
    【python】jieba分词,去停用词,自定义字典
    【python】jieba分词,简单版
    【python】散点图,读取excel数据,xlrd
    vhost文件配置含义是什么
    羊驼可以吃吗
    PHP中的sublime软件如何用快捷键移动到行尾或者行首
    PHP中单引号,双引号,的区别?
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6809424.html
Copyright © 2020-2023  润新知