链接:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87813#problem/J

Description

Daniel has a string s, consisting of lowercase English letters and period signs (characters '.'). Let's define the operation of replacement as the following sequence of steps: find a substring ".." (two consecutive periods) in string s, of all occurrences of the substring let's choose the first one, and replace this substring with string ".". In other words, during the replacement operation, the first two consecutive periods are replaced by one. If string s contains no two consecutive periods, then nothing happens.

Let's define f(s) as the minimum number of operations of replacement to perform, so that the string does not have any two consecutive periods left.

You need to process m queries, the i-th results in that the character at position xi (1 ≤ xi ≤ n) of string s is assigned value ci. After each operation you have to calculate and output the value of f(s).

Help Daniel to process all queries.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 300 000) the length of the string and the number of queries.

The second line contains string s, consisting of n lowercase English letters and period signs.

The following m lines contain the descriptions of queries. The i-th line contains integer xi and ci (1 ≤ xi ≤ nci — a lowercas English letter or a period sign), describing the query of assigning symbol ci to position xi.

Output

Print m numbers, one per line, the i-th of these numbers must be equal to the value of f(s) after performing the i-th assignment.

Sample Input

Input
10 3
.b..bz....
1 h
3 c
9 f
Output
4
3
1
Input
4 4
.cc.
2 .
3 .
2 a
1 a
Output
1
3
1
1

Hint

Note to the first sample test (replaced periods are enclosed in square brackets).

The original string is ".b..bz....".

  • after the first query f(hb..bz....) = 4    ("hb[..]bz...."  →  "hb.bz[..].."  →  "hb.bz[..]."  →  "hb.bz[..]"  →  "hb.bz.")
  • after the second query f(hbс.bz....) = 3    ("hbс.bz[..].."  →  "hbс.bz[..]."  →  "hbс.bz[..]"  →  "hbс.bz.")
  • after the third query f(hbс.bz..f.) = 1    ("hbс.bz[..]f."  →  "hbс.bz.f.")

Note to the second sample test.

The original string is ".cc.".

  • after the first query: f(..c.) = 1    ("[..]c."  →  ".c.")
  • after the second query: f(....) = 3    ("[..].."  →  "[..]."  →  "[..]"  →  ".")
  • after the third query: f(.a..) = 1    (".a[..]"  →  ".a.")
  • after the fourth query: f(aa..) = 1    ("aa[..]"  →  "aa.")

找到了规律很水的AC了,但看了题解后知道原来这是个线段树, 两个代码都粘一下

水的代码:

#include<stdio.h>
#include<string.h> #define N 301100 char s[N]; int main()
{
int n, m, sum, z;
while(scanf("%d%d", &n, &m)!=EOF)
{
char ch;
int k, i;
scanf("%s", s); sum=;
for(i=; i<n; i++)
{
z = ;
while(s[i]=='.' && i<n)
{
z++;
i++;
}
if(z)
sum+=z-;
} for(i=; i<=m; i++)
{
scanf("%d %c", &k, &ch); if((s[k-]!='.'&&ch!='.') || (s[k-]=='.'&&ch=='.') )
{
printf("%d\n", sum);
continue;
}
if(ch=='.' && s[k-]!='.')
{
if(s[k]!='.' && s[k-]!='.')
sum = sum;
else if(s[k]=='.' && s[k-]=='.')
sum += ;
else if(s[k]=='.' || s[k-]=='.')
sum += ;
}
if(ch!='.' && s[k-]=='.')
{
if(s[k]=='.' && s[k-]=='.')
sum = sum-;
else if(s[k]!='.' && s[k-]!='.')
sum = sum;
else if(s[k]!='.' || s[k-]!='.')
sum = sum-;
}
s[k-] = ch;
printf("%d\n", sum);
}
}
return ;
}

线段树:

/*************************************************************************
> File Name: C.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年08月14日 星期五 01时09分43秒
************************************************************************/ #include <iostream>
#include <fstream>
#include <cstring>
#include <climits>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <functional>
#include <algorithm> using namespace std; const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int, int> PLL;
const LL INF = (1LL << ); const int N = ;
struct SegTree {
int l, r;
int lenl, lenr;
int len;
int cnt;
}tree[N << ];
char str[N]; void pushup(int p)
{
tree[p].lenl = tree[p << ].lenl;
if (tree[p].lenl == tree[p << ].r - tree[p << ].l + )
{
tree[p].lenl += tree[p << | ].lenl;
}
tree[p].lenr = tree[p << | ].lenr;
if (tree[p].lenr == tree[p << | ].r - tree[p << | ].l + )
{
tree[p].lenr += tree[p << ].lenr;
}
tree[p].cnt = tree[p << ].cnt + tree[p << | ].cnt;
if (tree[p << ].lenr && tree[p << | ].lenl)
{
--tree[p].cnt;
}
tree[p].len = tree[p << ].len + tree[p << | ].len;
} void build(int p, int l, int r)
{
tree[p].l = l;
tree[p].r = r;
if (l == r) {
tree[p].cnt = tree[p].lenl = tree[p].lenr = tree[p].len = (str[l - ] == '.');
return;
}
int mid = (l + r) >> ;
build(p << , l, mid);
build(p << | , mid + , r);
pushup(p);
} void update(int p, int pos)
{
if (tree[p].l == tree[p].r)
{
tree[p].cnt = tree[p].lenl = tree[p].lenr = tree[p].len = (str[tree[p].l - ] == '.');
return;
}
int mid = (tree[p].l + tree[p].r) >> ;
if (pos <= mid)
{
update(p << , pos);
}
else
{
update(p << | , pos);
}
pushup(p);
} char v[];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
scanf("%s", str);
build(, , n);
int x;
while (m--)
{
scanf("%d%s", &x, v);
str[x - ] = v[];
update(, x);
printf("%d\n", tree[].len - tree[].cnt);
}
return ;
}

(线段树 && 字符串的处理)codeforces -- 570C的更多相关文章

  1. 线段树 + 字符串Hash - Codeforces 580E Kefa and Watch

    Kefa and Watch Problem's Link Mean: 给你一个长度为n的字符串s,有两种操作: 1 L R C : 把s[l,r]全部变为c; 2 L R d : 询问s[l,r]是 ...

  2. 线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E

    http://codeforces.com/contest/719/problem/E 题目大意:给你一串数组a,a[i]表示第i个斐波那契数列,有如下操作 ①对[l,r]区间+一个val ②求出[l ...

  3. HDU 3973 线段树+字符串hash

    题目大意: 不断修改字符串中的字母,然后询问区间字符串是否处于已给定的字符串集合中 这里将原来的字符串集合保存到hash表中,当然用map,set都没有问题 修改查询都用线段树实现,自己的query函 ...

  4. hdu3973 AC's String 线段树+字符串hash

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3973/ 题意是:给出一个模式串,再给出一些串组成一个集合,操作分为两种,一种是替换模式串中的一个字符,还有一种是 ...

  5. 数据结构(线段树):Educational Codeforces Round 6 620E. New Year Tree

    E. New Year Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...

  6. [bzoj2124]等差子序列——线段树+字符串哈希

    题目大意 给一个1到N的排列\(A_i\),询问是否存在\(p_i\),\(i>=3\),使得\(A_{p_1}, A_{p_2}, ... ,A_{p_len}\)是一个等差序列. 题解 显然 ...

  7. 线段树 C - Connected Components? CodeForces - 920E

    这个题目居然可以用线段树写,好震惊,如果不是在线段树专题肯定想不到,但是就算在线段树的专题里面,我也不太会怎么写. 这个题目大意是,给你n m n代表n个点,m代表m条边,然后就是m行,每行两个数字, ...

  8. codeforces 1217E E. Sum Queries? (线段树

    codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...

  9. 线段树详解 (原理,实现与应用)(转载自:http://blog.csdn.net/zearot/article/details/48299459)

    原文地址:http://blog.csdn.net/zearot/article/details/48299459(如有侵权,请联系博主,立即删除.) 线段树详解    By 岩之痕 目录: 一:综述 ...

随机推荐

  1. 【完结汇总】iKcamp出品基于Koa2搭建Node.js实战共十一堂课(含视频)

  2. SQL语句查询年龄分段分组查询

    此情况用于数据库中没有“年龄”这个字段,只有“出生日期”这个字段.先计算出“年龄”,在分组查询. 1.SELECT *, ROUND(DATEDIFF(CURDATE(), popBirthday)/ ...

  3. 求数组中的逆序对的数量----剑指offer36题

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数: 如数组{7,5,6,4},逆序对总共有5对,{7,5},{7,6},{7, ...

  4. IntelliJ IDEA SVN

    第一步:下载svn的客户端,通俗一点来说就是小乌龟啦!去电脑管理的软件管理里面可以直接下载,方便迅速 下载之后直接安装就好了,但是要注意这里的这个文件也要安装上,默认是不安装的,如果不安装,svn中的 ...

  5. jQuery源码解读二(apply和call)

    一.apply方法和call方法的用法: apply方法: 语法:apply(thisObj,[,argArray]) 定义:应用某一对象的一个方法,用另一个对象替换当前对象. 说明:如果argArr ...

  6. Go语言中cannot convert adminname (type interface {}) to type *: need type assertion的解决办法

    解决的办法是把string(adminname)替换为adminname.(string).其它类型也是类似.

  7. 常用快捷键及eclipise快捷键

    win+R 运行...win+D 桌面win+E 打开我的电脑win+F 搜索 ctrl+D删除光标所在行

  8. hdoj2859(矩阵DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2859 思路: 第一次碰到这种矩阵上的DP题,想了半天也没想明白.本来想用子矩阵的左上角坐标和右下角坐标 ...

  9. 神龟快跑,2016做的一款UWP游戏

    神龟快跑,2016做的一款UWP游戏, 实际是H5页面, 用LAYA转AS3得到的 安装地址 https://www.microsoft.com/zh-cn/store/p/神龟快跑/9nblggh4 ...

  10. 交叉字符串 · Interleaving String

    [抄题]: 给出三个字符串:s1.s2.s3,判断s3是否由s1和s2交叉构成.(洗牌) 比如 s1 = "aabcc" s2 = "dbbca" - 当 s3 ...