• I


    题目链接:

    I - Magic

     FZU - 2280 

    学习链接:

    FZU - 2280 I - Magic 

    题目大意:

    给你nn个字符串,每个字符串有一个值ww,有qq次询问,一共两种操作:一是“1,x,y”“1,x,y”表示把第xx个串的ww变为yy;二是“2,x”2,x”,输出第xx个串能放几次魔法。放魔法的条件是这样:用串x放魔法,如果在1~n个串中,一个串的ww不超过xx的ww并且xx是这个串的后缀,则算放了一次魔法,然后每次询问输出能放几个魔法。

    具体思路:对于每个字符串hash一下,判断后缀,通过字符串hash判断就可以了。然后每次查询的时候O(n)查询就可以了。

    AC代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cmath>
     4 #include<string>
     5 #include<cstring>
     6 using namespace std;
     7 # define ll long long
     8 # define ull unsigned long long
     9 # define inf 0x3f3f3f3f
    10 const int ull base=131;
    11 const int maxn = 2e5+100;
    12 char str[maxn];
    13 ull Hash[1000+10][1000+10],ind[maxn];
    14 int val[maxn],length[maxn];
    15 void init()
    16 {
    17     ind[0]=1;
    18     for(int i=1; i<10000; i++)
    19     {
    20         ind[i]=ind[i-1]*base;
    21     }
    22 }
    23 void hs(int id,char *s)
    24 {
    25     int len=strlen(s+1);
    26     Hash[id][0]=0;
    27     for(int i=1; i<=len; i++)
    28     {
    29         Hash[id][i]=Hash[id][i-1]*base+(ull)s[i];
    30     }
    31 }
    32 ull getsub(int id,int l,int r)
    33 {
    34     return Hash[id][r]-Hash[id][l-1]*ind[r-l+1];
    35 }
    36 int n;
    37 int cal(int t)
    38 {
    39     int ans=0;
    40     ull tmp=getsub(t,1,length[t]);
    41     for(int i=1; i<=n; i++)
    42     {
    43         if(val[i]>val[t]||length[i]<length[t])
    44             continue;
    45         ull tmpans=getsub(i,length[i]-length[t]+1,length[i]);
    46         if(tmpans==tmp)
    47             ans++;
    48     }
    49     return ans;
    50 }
    51 int main()
    52 {
    53     init();
    54     int T;
    55     scanf("%d",&T);
    56     while(T--)
    57     {
    58         scanf("%d",&n);
    59         for(int i=1; i<=n; i++)
    60         {
    61             scanf("%s",str+1);
    62             hs(i,str);
    63             scanf("%d",&val[i]);
    64             length[i]=strlen(str+1);
    65         }
    66         int m;
    67         scanf("%d",&m);
    68         int op,st,ed;
    69         for(int i=1; i<=m; i++)
    70         {
    71             scanf("%d",&op);
    72             if(op==1)
    73             {
    74                 scanf("%d %d",&st,&ed);
    75                 val[st]=ed;
    76             }
    77             else
    78             {
    79                 scanf("%d",&st);
    80                 int ans=cal(st);
    81                 printf("%d
    ",ans);
    82             }
    83         }
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    我已经迷失在事件环(eventloop)中了【Nodejs篇】
    canvas练手项目(二)——各种操作基础
    canvas练手项目(三)——Canvas中的Text文本
    canvas练手项目(一)——选取图片
    迭代器,生成器(generator)和Promise的“微妙”关系
    通过HTTP的HEADER完成各种骚操作
    这份Koa的简易Router手敲指南请收下
    KOA的简易模板引擎实现方式
    扒一扒PROMISE的原理,大家不要怕!
    参考KOA,5步手写一款粗糙的web框架
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10700953.html
Copyright © 2020-2023  润新知