zoukankan      html  css  js  c++  java
  • ural 1989(树状数组+多项式hash)

    题意:给出一个字符串。有两种操作,一个是p a b,问字符串从位置a到位置b的子串是否是一个回文子串。还有一个操作 c a b,把字符串位置a的字符替换为b。

    题解:由于字符串长度为1e5且问的次数也有1e5,所以暴力肯定是会超时的,然后考虑用树状数组维护字符串的hash值来解,两个操作分别用正反方向区间比对哈希值和单点改动。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define ULL unsigned long long
    using namespace std;
    const int N = 100005;
    int n, m, l, r, pos;
    char str[N], q[20], c;
    ULL C[N][2], Hash[N];
    
    int lowbit(int x) {
    	return x & (-x);
    }
    
    ULL Sum(int x, int y) {
    	ULL ret = 0;
    	while (x > 0) {
    		ret += C[x][y];
    		x -= lowbit(x);
    	}
    	return ret;
    }
    
    void Add(int x, ULL d, int y) {
    	while (x <= n) {
    		C[x][y] += d;
    		x += lowbit(x);
    	}
    }
    
    int main() {
    	Hash[0] = 1;
    	for (int i = 1; i < N; i++)
    		Hash[i] = Hash[i - 1] * 27;//都是小写字母
    	while (scanf("%s", str) == 1) {
    		memset(C, 0, sizeof(C));
    		n = strlen(str);
    		for (int i = 0; i < n; i++) {
    			Add(i + 1, (str[i] - 'a') * Hash[i], 0);
    			Add(i + 1, (str[n - i - 1] - 'a') * Hash[i], 1);
    		}
    		scanf("%d", &m);
    		while (m--) {
    			scanf("%s", q);
    			if (q[0] == 'p') {
    				scanf("%d%d", &l, &r);
    				ULL h1 = (Sum(r, 0) - Sum(l - 1, 0)) * Hash[n - r];
    				ULL h2 = (Sum(n - l + 1, 1) - Sum(n - r, 1)) * Hash[l - 1];
    				if (h1 == h2)
    					printf("Yes
    ");
    				else
    					printf("No
    ");
    			}
    			else {
    				scanf("%d %c", &pos, &c);
    				int x = c - str[pos - 1];
    				Add(pos, x * Hash[pos - 1], 0);
    				Add(n - pos + 1, x * Hash[n - pos], 1);
    				str[pos - 1] = c;
    			}
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    thinkphp使用ajax
    thinkphp修改和删除数据
    thinkphp添加数据
    thinkphp中的查询语句
    thinkphp模型
    空控制器的处理
    thinkphp3.2.3版本文件目录及作用
    12月18日Smarty文件缓存
    12月15日smarty模板基本语法
    12月13日上午Smarty模版原理
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7002903.html
Copyright © 2011-2022 走看看