链接:

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. ssh反向连接内网主机

    holer听别人说也挺好用不过本人没试过:https://github.com/Wisdom-Projects/holer 利用autossh建立稳定隧道,前提双方互加公钥信任. # yum inst ...

  2. linux配置裸设备

    1.什么裸设备?字符设备?块设备? 裸设备:也叫裸分区(原始分区),是一种没有经过格式化,不被Unix/Linux通过文件系统来读取的特殊字符设备.它由应用程序负责对它进行读写操作.不经过文件系统的缓 ...

  3. 趣味编程:24点(Haskell版)

    24 game/Solve import Data.List import Data.Ratio import Control.Monad data Expr = Constant Rational ...

  4. hadoop发行版本

    Azure HDInsight Azure HDInsight is Microsoft's distribution of Hadoop. The Azure HDInsight ecosystem ...

  5. fio 测试磁盘

    root@rook-test:/# ceph osd status+----+-----------------------------+-------+-------+--------+------ ...

  6. 带图标的input

    <style> .text{ border:solid 2px #ccc; width:400px; height:40px; background:url(http://d.lanren ...

  7. HttpClient(一)

    package com.cmy.httpClient; import org.apache.commons.httpclient.HttpClient; import org.apache.commo ...

  8. Django的models操作

    一.先看单表操作 增 方式1: models.book.objects.create( Book_name = "aaa", Book_info = "bbb" ...

  9. 11-简单解释spingmvc项目的结构

    可以简单的理解为下面这样子:

  10. mvc 封装控件使用mvcpager

    具体使用如下: 前台部分: @RenderPage("~/Views/Controls/_Pagebar.cshtml", new PageBar { pageIndex = Mo ...