Magic FZU

来源:互联网 发布:知豆电动汽车连锁店 编辑:程序博客网 时间:2024/05/16 07:47

给定n个字符串,每个字符串一个价值wi,询问

1 更改某个串的价值

2 查询以第x个串为后缀且价值小等于x串的字符串个数

字符串个数 n<=1000

查询数 q<=80000

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespace std;const int x = 131;const int mx = 1005;typedef unsigned long long ul;ul h[mx][mx];ul xp[mx];int len[mx];char s[mx][mx];int a[mx];int n,q;void geth(){    xp[0] = 1;    for(int i = 1; i <= 1000; i++)        xp[i] = xp[i-1]*x;    for(int i = 1; i <= n; i++){        h[i][len[i]] = 0;        for(int j = len[i]-1; j >= 0; j--)            h[i][j] = h[i][j+1]*x + (s[i][j]-'a');    }}ul HASH(int i,int j,int l){    return h[i][j]-h[i][j+l]*xp[l];}int search(int x){    int ans = 0;    for(int i = 1; i <= n; i++){        if(a[i]>a[x])            continue;        if(len[x] == len[i])            ans += HASH(x,0,len[x])==HASH(i,0,len[x]);        else if(len[x] < len[i])            ans += HASH(x,0,len[x])==HASH(i,len[i]-len[x],len[x]);    }    return ans;}int main(){    int t;    scanf("%d",&t);    while(t--){        scanf("%d",&n);        for(int i = 1; i <= n; i++){            scanf("%s%d",s[i],&a[i]);            len[i] = strlen(s[i]);        }        geth();        scanf("%d",&q);        while(q--){            int casei,x,y;            scanf("%d",&casei);            if(casei == 2){                scanf("%d",&x);                printf("%d\n",search(x));            }            else{                scanf("%d%d",&x,&y);                a[x] = y;            }        }    }    return 0;}