• 金山西山居初赛第三场 HDU 4551~HDU 4553


    第一个题就不说了,注意闰年的2月29。

     1 #include <map>
     2 #include <set>
     3 #include <list>
     4 #include <queue>
     5 #include <stack>
     6 #include <cmath>
     7 #include <ctime>
     8 #include <vector>
     9 #include <bitset>
    10 #include <cstdio>
    11 #include <string>
    12 #include <numeric>
    13 #include <cstring>
    14 #include <cstdlib>
    15 #include <iostream>
    16 #include <algorithm>
    17 #include <functional>
    18 using namespace std;
    19 typedef long long  ll;
    20 typedef unsigned long long ull;
    21 
    22 int dx[4]={-1,1,0,0};
    23 int dy[4]={0,0,-1,1};//up down left right
    24 bool inmap(int x,int y,int n,int m){if(x<1||x>n||y<1||y>m)return false;return true;}
    25 int hashmap(int x,int y,int m){return (x-1)*m+y;}
    26 
    27 #define eps 1e-8
    28 #define inf 0x7ffffff
    29 #define debug puts("BUG")
    30 #define lson l,m,rt<<1
    31 #define rson m+1,r,rt<<1|1
    32 #define read freopen("in.txt","r",stdin)
    33 #define write freopen("out.txt","w",stdout)
    34 #define maxn 1005
    35 int d[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    36 int cnt[maxn][maxn];
    37 struct str
    38 {
    39     int m,d;
    40 }nd[maxn][maxn];
    41 bool isY(int y)
    42 {
    43     if(y%400==0)return true;
    44     if(y%100==0)return false;
    45     return y%4==0;
    46 }
    47 int gcd(int a,int b)
    48 {
    49     if(b==0)return  a;
    50     return gcd(b,a%b);
    51 }
    52 void init()
    53 {
    54     memset(cnt,0,sizeof(cnt));
    55     for(int i=1;i<13;++i)
    56     {
    57         for(int j=1;j<=d[i];++j)
    58         {
    59             int t=gcd(i,j),t2=i*j/t;
    60             ++cnt[t][t2];
    61             nd[t][t2].m=i,nd[t][t2].d=j;
    62         }
    63     }
    64 }
    65 int main()
    66 {
    67     //read;
    68     int cas;
    69     init();
    70     scanf("%d",&cas);
    71     for(int xx=1;xx<=cas;++xx)
    72     {
    73         int a,b,y;
    74         scanf("%d%d%d",&a,&b,&y);
    75         if(isY(y)&&a==1&&b==58)
    76             printf("Case #%d: %04d/%02d/%02d\n",xx,y,2,29);
    77         else
    78         {
    79             if(cnt[a][b]==0)
    80                 printf("Case #%d: -1\n",xx);
    81             else if(cnt[a][b]>1)
    82                 printf("Case #%d: 1\n",xx);
    83             else printf("Case #%d: %04d/%02d/%02d\n",xx,y,nd[a][b].m,nd[a][b].d);
    84         }
    85     }
    86     return 0;
    87 }
    View Code

    第二题,题干啰嗦了一堆,又是ASCII码又是循环次数的,貌似其实就是让求所有前缀出现的次数和mod256。

    一种正常方法是求所有后缀和最长后缀的最长公共前缀的和,拿第二个样例举例:

    0 abab

    1 bab

    2 ab

    3 b

    0跟2的最长公共前缀是2,所以能对最后的答案有2个贡献,0跟自己的最长公共前缀是4,所以对最后答案贡献4,最后答案就是6。

    这里求最长公共前缀一般需要RMQ预处理,但求所有后缀跟同一个后缀的最长公共前缀就不用了,利用后缀数组的排名性质,找到原串在后缀中的排名,分别向上和向下扫就OK。

      1 #include <map>
      2 #include <set>
      3 #include <list>
      4 #include <queue>
      5 #include <stack>
      6 #include <cmath>
      7 #include <ctime>
      8 #include <vector>
      9 #include <bitset>
     10 #include <cstdio>
     11 #include <string>
     12 #include <numeric>
     13 #include <cstring>
     14 #include <cstdlib>
     15 #include <iostream>
     16 #include <algorithm>
     17 #include <functional>
     18 using namespace std;
     19 typedef long long  ll;
     20 typedef unsigned long long ull;
     21 
     22 int dx[4]={-1,1,0,0};
     23 int dy[4]={0,0,-1,1};//up down left right
     24 bool inmap(int x,int y,int n,int m){if(x<1||x>n||y<1||y>m)return false;return true;}
     25 int hashmap(int x,int y,int m){return (x-1)*m+y;}
     26 
     27 #define eps 1e-8
     28 #define inf 0x7fffffff
     29 #define debug puts("BUG")
     30 #define lson l,m,rt<<1
     31 #define rson m+1,r,rt<<1|1
     32 #define read freopen("in.txt","r",stdin)
     33 #define write freopen("out.txt","w",stdout)
     34 
     35 #define maxn 100005
     36 int wa[maxn],wb[maxn],wv[maxn],wu[maxn];
     37 int cmp(int *r,int a,int b,int l)
     38 {return r[a]==r[b]&&r[a+l]==r[b+l];}
     39 void da(int *r,int *sa,int n,int m)    //求SA[]
     40 {
     41      int i,j,p,*x=wa,*y=wb,*t;
     42      for(i=0;i<m;i++) wu[i]=0;
     43      for(i=0;i<n;i++) wu[x[i]=r[i]]++;
     44      for(i=1;i<m;i++) wu[i]+=wu[i-1];
     45      for(i=n-1;i>=0;i--) sa[--wu[x[i]]]=i;
     46      for(j=1,p=1;p<n;j*=2,m=p)
     47      {
     48        for(p=0,i=n-j;i<n;i++) y[p++]=i;
     49        for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
     50        for(i=0;i<n;i++) wv[i]=x[y[i]];
     51        for(i=0;i<m;i++) wu[i]=0;
     52        for(i=0;i<n;i++) wu[wv[i]]++;
     53        for(i=1;i<m;i++) wu[i]+=wu[i-1];
     54        for(i=n-1;i>=0;i--) sa[--wu[wv[i]]]=y[i];
     55        for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
     56        x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
     57      }
     58      return;
     59 }
     60 int rank[maxn],height[maxn];
     61 void calheight(int *r,int *sa,int n)    //求height[]
     62 {
     63      int i,j,k=0;
     64      for(i=1;i<=n;i++) rank[sa[i]]=i;
     65      for(i=0;i<n;height[rank[i++]]=k)
     66      for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
     67      return;
     68 }
     69 #define mod 256
     70 char ss[maxn];
     71 int r[maxn],sa[maxn];
     72 int gao(int len)
     73 {
     74     int ans=len%mod,mx=inf;
     75     for(int i=rank[0];i;--i)
     76     {
     77         mx=min(mx,height[i]);
     78         ans+=mx;
     79         while(ans>=mod)ans-=mod;
     80     }mx=inf;
     81     for(int i=rank[0]+1;i<=len;++i)
     82     {
     83         mx=min(mx,height[i]);
     84         ans+=mx;
     85         while(ans>=mod)ans-=mod;
     86     }
     87     return ans;
     88 }
     89 int main()
     90 {
     91     //read;
     92     while(~scanf("%s",ss))
     93     {
     94         int len=strlen(ss);
     95         for(int i=0;i<len;++i)
     96             r[i]=ss[i];
     97         r[len]=0;
     98         da(r,sa,len+1,128);
     99         calheight(r,sa,len);
    100         printf("%d\n",gao(len));
    101     }
    102     return 0;
    103 }
    View Code

    比赛的时候不是用的这个做法,因为没有很快想到……。当时看了一下题,统计的是所有的前缀,想到了KMP……。利用NEXT数组的性质,求NEXT[k]的时候会求出1~K这个串前缀和后缀的最长公共前缀(好绕),所以对于每一个k,如果next[k]!=-1,那么就会跟一个原串的某个前缀重复,对答案的贡献就+1。所以求出给出字符串的next,就能求答案了。

     1 #include <map>
     2 #include <set>
     3 #include <list>
     4 #include <queue>
     5 #include <stack>
     6 #include <cmath>
     7 #include <ctime>
     8 #include <vector>
     9 #include <bitset>
    10 #include <cstdio>
    11 #include <string>
    12 #include <numeric>
    13 #include <cstring>
    14 #include <cstdlib>
    15 #include <iostream>
    16 #include <algorithm>
    17 #include <functional>
    18 using namespace std;
    19 typedef long long  ll;
    20 typedef unsigned long long ull;
    21 
    22 int dx[4]={-1,1,0,0};
    23 int dy[4]={0,0,-1,1};//up down left right
    24 bool inmap(int x,int y,int n,int m){if(x<1||x>n||y<1||y>m)return false;return true;}
    25 int hashmap(int x,int y,int m){return (x-1)*m+y;}
    26 
    27 #define eps 1e-8
    28 #define inf 0x7ffffff
    29 #define debug puts("BUG")
    30 #define lson l,m,rt<<1
    31 #define rson m+1,r,rt<<1|1
    32 #define read freopen("in.txt","r",stdin)
    33 #define write freopen("out.txt","w",stdout)
    34 #define maxn 100005
    35 char substr[maxn];
    36 int sublen,next[maxn];
    37 void get_next()
    38 {
    39     sublen=strlen(substr);
    40     next[0] = -1;
    41     for(int i=1,j=-1;i<sublen;i++)
    42     {
    43         while(j>-1&&substr[j+1]!=substr[i])j=next[j] ;
    44         if(substr[j+1]==substr[i])j++;
    45         next[i]=j;
    46     }
    47 }
    48 int main()
    49 {
    50     //read;
    51     while(~scanf("%s",substr))
    52     {
    53         get_next();int ans=sublen;
    54         for(int i=0;i<sublen;++i)
    55         {
    56             int j=i;
    57             while(~next[j])
    58             {
    59                 ++ans;
    60                 while(ans>=256)ans-=256;
    61                 j=next[j];
    62             }
    63         }
    64         printf("%d\n",ans);
    65     }
    66     return 0;
    67 }
    View Code

    此题的数据绝对的水,因为当时提交的时候发现取模的时候没用while,应该是错的,结果返回了AC。而且用的时间也太少了,不知道用求NEXT的做法时间复杂度具体是多少,不过应该不会这么快。数据弱的都怀疑自己的做法的正确性。

    第三题,做法一目了然,区间合并的线段树,就是维护的信息比较多,由于有女神的存在,需要建两棵树。注意,更新NS那颗树的时候一定也要更新DS那颗树。还有当时读题的时候有个地方不是很清楚,STUDY操作需要清空一个区间的所有请求,这个请求到底指的什么?比如跟NS约会约到一半,突然想STUDY了,可是NS的请求是在STUDY前开始的,到底需不需要清空。后来想,如果不清空就不能用线段树做了吧,干脆就按正常的区间更新做。最后发现按照区间更新做就行,想太多了。

    这个题其实就是POJ 3667 Hotel这道题的升级版。

      1 #include <map>
      2 #include <set>
      3 #include <list>
      4 #include <queue>
      5 #include <stack>
      6 #include <cmath>
      7 #include <ctime>
      8 #include <vector>
      9 #include <bitset>
     10 #include <cstdio>
     11 #include <string>
     12 #include <numeric>
     13 #include <cstring>
     14 #include <cstdlib>
     15 #include <iostream>
     16 #include <algorithm>
     17 #include <functional>
     18 using namespace std;
     19 typedef long long  ll;
     20 typedef unsigned long long ull;
     21 
     22 int dx[4]={-1,1,0,0};
     23 //int dy[4]={0,0,-1,1};//up down left right
     24 bool inmap(int x,int y,int n,int m){if(x<1||x>n||y<1||y>m)return false;return true;}
     25 int hashmap(int x,int y,int m){return (x-1)*m+y;}
     26 
     27 #define eps 1e-8
     28 #define inf 0x7fffffff
     29 #define debug puts("BUG")
     30 #define lson l,m,rt<<1
     31 #define rson m+1,r,rt<<1|1
     32 #define read freopen("in.txt","r",stdin)
     33 #define write freopen("out.txt","w",stdout)
     34 #define maxn 100005
     35 int ml[maxn<<2],mr[maxn<<2],mx[maxn<<2];
     36 int ml1[maxn<<2],mr1[maxn<<2],mx1[maxn<<2];
     37 int dd[maxn<<2],dd1[maxn<<2];
     38 void pushup(int rt,int l)
     39 {
     40     int l2=l>>1,l1=l-l2;
     41     ml[rt]=ml[rt<<1];
     42     mr[rt]=mr[rt<<1|1];
     43     if(ml[rt]==l1)ml[rt]+=ml[rt<<1|1];
     44     if(mr[rt]==l2)mr[rt]+=mr[rt<<1];
     45     mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
     46     mx[rt]=max(mx[rt],mr[rt<<1]+ml[rt<<1|1]);
     47 }
     48 void pushdown(int rt,int l)
     49 {
     50     if(dd[rt]!=-1)
     51     {
     52         int l2=l>>1,l1=l-l2;
     53         dd[rt<<1]=dd[rt<<1|1]=dd[rt];
     54         mx[rt<<1]=ml[rt<<1]=mr[rt<<1]=dd[rt]*l1,
     55         mx[rt<<1|1]=ml[rt<<1|1]=mr[rt<<1|1]=dd[rt]*l2;
     56         dd[rt]=-1;
     57     }
     58 }
     59 void pushup1(int rt,int l)
     60 {
     61     int l2=l>>1,l1=l-l2;
     62     ml1[rt]=ml1[rt<<1];
     63     mr1[rt]=mr1[rt<<1|1];
     64     if(ml1[rt]==l1)ml1[rt]+=ml1[rt<<1|1];
     65     if(mr1[rt]==l2)mr1[rt]+=mr1[rt<<1];
     66     mx1[rt]=max(mx1[rt<<1],mx1[rt<<1|1]);
     67     mx1[rt]=max(mx1[rt],mr1[rt<<1]+ml1[rt<<1|1]);
     68 }
     69 void pushdown1(int rt,int l)
     70 {
     71     if(dd1[rt]!=-1)
     72     {
     73         int l2=l>>1,l1=l-l2;
     74         dd1[rt<<1]=dd1[rt<<1|1]=dd1[rt];
     75         mx1[rt<<1]=ml1[rt<<1]=mr1[rt<<1]=dd1[rt]*l1,
     76         mx1[rt<<1|1]=ml1[rt<<1|1]=mr1[rt<<1|1]=dd1[rt]*l2;
     77         dd1[rt]=-1;
     78     }
     79 }
     80 void build(int l,int r,int rt)
     81 {
     82     dd[rt]=dd1[rt]=-1;
     83     if(l==r)
     84     {
     85         ml[rt]=mr[rt]=mx[rt]=1;
     86         ml1[rt]=mr1[rt]=mx1[rt]=1;
     87         return ;
     88     }
     89     int m=(l+r)>>1;
     90     build(lson),build(rson);
     91     pushup(rt,r-l+1);
     92     pushup1(rt,r-l+1);
     93 }
     94 void update(int l1,int r1,int v,int l,int r,int rt)
     95 {
     96     if(l1<=l&&r1>=r)
     97     {
     98         mx[rt]=ml[rt]=mr[rt]=v*(r-l+1);
     99         dd[rt]=v;
    100         return ;
    101     }
    102     pushdown(rt,r-l+1);
    103     int m=(l+r)>>1;
    104     if(l1<=m)update(l1,r1,v,lson);
    105     if(r1>m)update(l1,r1,v,rson);
    106     pushup(rt,r-l+1);
    107 }
    108 void update1(int l1,int r1,int v,int l,int r,int rt)
    109 {
    110     if(l1<=l&&r1>=r)
    111     {
    112         mx1[rt]=ml1[rt]=mr1[rt]=v*(r-l+1);
    113         dd1[rt]=v;
    114         return ;
    115     }
    116     pushdown1(rt,r-l+1);
    117     int m=(l+r)>>1;
    118     if(l1<=m)update1(l1,r1,v,lson);
    119     if(r1>m)update1(l1,r1,v,rson);
    120     pushup1(rt,r-l+1);
    121 }
    122 int query(int p,int l,int r,int rt)
    123 {
    124     if(l==r)return l;
    125     pushdown(rt,r-l+1);
    126     int m=(l+r)>>1,ans;
    127     if(mx[rt<<1]>=p)ans=query(p,lson);
    128     else if(mr[rt<<1]+ml[rt<<1|1]>=p)ans=m-mr[rt<<1]+1;
    129     else ans=query(p,rson);
    130     return ans;
    131 }
    132 int query1(int p,int l,int r,int rt)
    133 {
    134     if(l==r)return l;
    135     pushdown1(rt,r-l+1);
    136     int m=(l+r)>>1,ans;
    137     if(mx1[rt<<1]>=p)ans=query1(p,lson);
    138     else if(mr1[rt<<1]+ml1[rt<<1|1]>=p)ans=m-mr1[rt<<1]+1;
    139     else ans=query1(p,rson);
    140     return ans;
    141 }
    142 char ss[maxn];
    143 int main()
    144 {
    145     //read;
    146     int n,m,cas;
    147     scanf("%d",&cas);
    148     for(int xx=1;xx<=cas;++xx)
    149     {
    150         printf("Case %d:\n",xx);
    151         scanf("%d%d",&n,&m);
    152         build(1,n,1);
    153         int b,c;
    154         while(m--)
    155         {
    156             scanf("%s",ss);
    157             if(ss[0]=='D')
    158             {
    159                 scanf("%d",&b);
    160                 if(mx[1]<b)puts("fly with yourself");
    161                 else
    162                 {
    163                     int p=query(b,1,n,1);
    164                     printf("%d,let's fly\n",p);
    165                     update(p,p+b-1,0,1,n,1);
    166                 }
    167             }
    168             else if(ss[0]=='N')
    169             {
    170                 scanf("%d",&b);
    171                 if(mx[1]>=b)
    172                 {
    173                     int p=query(b,1,n,1);
    174                     printf("%d,don't put my gezi\n",p);
    175                     update(p,p+b-1,0,1,n,1);
    176                     update1(p,p+b-1,0,1,n,1);
    177                 }
    178                 else
    179                 {
    180                     if(mx1[1]<b)puts("wait for me");
    181                     else
    182                     {
    183                         int p=query1(b,1,n,1);
    184                         printf("%d,don't put my gezi\n",p);
    185                         update(p,p+b-1,0,1,n,1);
    186                         update1(p,p+b-1,0,1,n,1);
    187                     }
    188                 }
    189             }
    190             else
    191             {
    192                 scanf("%d%d",&b,&c);
    193                 update(b,c,1,1,n,1);
    194                 update1(b,c,1,1,n,1);
    195                 puts("I am the hope of chinese chengxuyuan!!");
    196             }
    197         }
    198     }
    199     return 0;
    200 }
    View Code
  • 相关阅读:
    Linux下的内核测试工具——perf使用简介
    浅谈C++中指针和引用的区别
    成为Java顶尖程序员 ,看这11本书就够了
    spring注解详解
    Spring AOP详解和实现方式
    Spring IoC中各个注解的理解和使用
    NameNode配置HA后及其反过程Hive路径不正确的问题解决
    [maven] 常用插件解析
    Saiku3.15去除License与主界面
    saiku系列文章
  • 原文地址:https://www.cnblogs.com/mcflurry/p/3086640.html
Copyright © 2020-2023  润新知