zoukankan      html  css  js  c++  java
  • [CF580E]Kefa and Watch

    题目大意:
    维护一个由'0'~'9'构成的字符串,支持以下两种操作:
    1.将指定区间内的所有字符修改为同一指定字符。
    2.询问$x$是否为指定区间内的循环节。

    思路:
    建立一棵线段树,维护每个子串的哈希值。

    实现细节:
    1.Lazy-tag需要初始化成$-1$,因为$0$也是字符串中的元素,会混淆。
    2.预处理出seed的$n$次幂及其前缀和,可以优化常数。
    3.查询时需要合并两个区间的哈希值,需要考虑$mid<r$和$midgeq r$两种情况。

    其它:
    这题调不出的时候打了一个暴力对拍,加过发现暴力能直接AC。

    标算代码:

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 inline int getint() {
     5     char ch;
     6     while(!isdigit(ch=getchar()));
     7     int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 inline int getdigit() {
    12     char ch;
    13     while(!isdigit(ch=getchar()));
    14     return ch^'0';
    15 }
    16 const int N=100001;
    17 int n;
    18 class SegmentTree {
    19     #define mid ((b+e)>>1)
    20     #define _left <<1
    21     #define _right <<1|1
    22     private:
    23         int val[N<<2],tag[N<<2],pow[N],pre[N];
    24         static const int seed=131,mod=19260817;
    25         void push_up(const int p,const int b,const int e) {
    26             val[p]=((long long)val[p _left]*pow[e-mid]%mod+val[p _right])%mod;
    27         }
    28         void push_down(const int p,const int b,const int e) {
    29             if(tag[p]==-1) return;
    30             tag[p _left]=tag[p _right]=tag[p];
    31             val[p _left]=(long long)tag[p]*pre[mid-b]%mod;
    32             val[p _right]=(long long)tag[p]*pre[e-mid-1]%mod;
    33             tag[p]=-1;
    34         }
    35         int query(const int p,const int b,const int e,const int l,const int r) {
    36             if((b==l)&&(e==r)) return val[p];
    37             push_down(p,b,e);
    38             int ret=0;
    39             if(l<=mid) ret=(long long)(ret+query(p _left,b,mid,l,std::min(mid,r)))*pow[std::max(r-mid,0)]%mod;
    40             if(r>mid) ret=(ret+query(p _right,mid+1,e,std::max(mid+1,l),r))%mod;
    41             return ret;
    42         }
    43     public:
    44         SegmentTree() {
    45             pre[0]=pow[0]=1;
    46             for(int i=1;i<N;i++) {
    47                 pow[i]=(long long)pow[i-1]*seed%mod;
    48                 pre[i]=(pow[i]+pre[i-1])%mod;
    49             }
    50         }
    51         void build(const int p,const int b,const int e) {
    52             tag[p]=-1;
    53             if(b==e) {
    54                 val[p]=getdigit();
    55                 return;
    56             }
    57             build(p _left,b,mid);
    58             build(p _right,mid+1,e);
    59             push_up(p,b,e);
    60         }
    61         void modify(const int p,const int b,const int e,const int l,const int r,const int x) {
    62             if((b==l)&&(e==r)) {
    63                 val[p]=x*pre[e-b];
    64                 tag[p]=x;
    65                 return;
    66             }
    67             push_down(p,b,e);
    68             if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x);
    69             if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,x);
    70             push_up(p,b,e);
    71         }
    72         bool check(const int l,const int r,const int x) {
    73             if(x<=0||x>=r-l+1) return true;
    74             return query(1,1,n,l,r-x)==query(1,1,n,l+x,r);
    75         }
    76 };
    77 SegmentTree t;
    78 int main() {
    79     n=getint();
    80     int m=getint()+getint();
    81     t.build(1,1,n);
    82     while(m--) {
    83         int d=getint(),l=getint(),r=getint(),c=getint();
    84         if(d==1) t.modify(1,1,n,l,r,c);
    85         if(d==2) puts(t.check(l,r,c)?"YES":"NO");
    86     }
    87     return 0;
    88 }
    View Code

    暴力代码:

     1 #include<cstdio>
     2 #include<cctype>
     3 inline int getint() {
     4     char ch;
     5     while(!isdigit(ch=getchar()));
     6     int x=ch^'0';
     7     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     8     return x;
     9 }
    10 inline int getdigit() {
    11     char ch;
    12     while(!isdigit(ch=getchar()));
    13     return ch^'0';
    14 }
    15 int main() {
    16     int n=getint(),m=getint()+getint();
    17     int a[n+1];
    18     for(int i=1;i<=n;i++) a[i]=getdigit();
    19     while(m--) {
    20         int d=getint(),l=getint(),r=getint(),c=getint();
    21         if(d==1) {
    22             for(int i=l;i<=r;i++) a[i]=c;
    23         }
    24         if(d==2) {
    25             for(int i=1;i<=c;i++) {
    26                 for(int j=l-1+i+c;j<=r;j+=c) {
    27                     if(a[j]!=a[j-c]) {
    28                         puts("NO");
    29                         goto Next;
    30                     }
    31                 }
    32             }
    33             puts("YES");
    34         }
    35         Next:;
    36     }
    37     return 0;
    38 }
    View Code

    数据生成器:

     1 #include<ctime>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 int main() {
     5     srand(time(NULL));
     6     int n=10,m=10;
     7     printf("%d %d %d
    ",n,m,0);
     8     for(int i=1;i<=n;i++) {
     9         int d=rand()%10;
    10         printf("%d",d);
    11     }
    12     puts("");
    13     for(int i=1;i<=m;i++) {
    14         int d=rand()%2+1,l=rand()%n+1,r=rand()%(n-l+1)+l;
    15         int c=(d==1)?(rand()%10):(rand()%(r-l+1));
    16         printf("%d %d %d %d
    ",d,l,r,c);
    17     }
    18     return 0;
    19 }
    View Code

    对拍程序:

    1 @echo off
    2 :loop
    3     data.exe >input.txt
    4     SimpleOJ206.exe <input.txt >hash.txt
    5     SimpleOJ206scx.exe <input.txt >scx.txt
    6     fc hash.txt scx.txt
    7     if errorlevel 1 pause
    8 goto loop 
    View Code

    用来手算哈希的计算器:

    1 while 1:
    2     import os
    3     print(eval(input()))
    4     os.system("pause")
    View Code
  • 相关阅读:
    GFS.BigTable.MapReduce谷歌论文学习笔记
    Android图表
    JAVA内存管理
    关于Ajax工作原理
    走进AngularJs(二) ng模板中常用指令的使用方式
    走进AngularJs(一)angular基本概念的认识与实战
    使用CSS3 制作一个material-design 风格登录界面
    一分钟搞定AlloyTouch图片轮播
    PHP+JQUEY+AJAX实现分页
    全面的Seo面试题
  • 原文地址:https://www.cnblogs.com/skylee03/p/7380224.html
Copyright © 2011-2022 走看看