CodeForces

来源:互联网 发布:软件成本估算专家 编辑:程序博客网 时间:2024/05/17 12:19

C. Replacement
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Daniel has a string s, consisting of lowercase English letters and period signs (characters '.'). Let's define the operation ofreplacement as the following sequence of steps: find a substring ".." (two consecutive periods) in strings, 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 ofreplacement 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 strings is assigned value ci. After each operation you have to calculate and output the value off(s).

Help Daniel to process all queries.

Input

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

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

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

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.

Examples
Input
10 3.b..bz....1 h3 c9 f
Output
431
Input
4 4.cc.2 .3 .2 a1 a
Output
1311
Note

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.")
思维题, 题意如下;

给出一个字符串,如果在字符串中遇到两个相邻的'.',把这两个点合并为一个点,直到找不到连续的两个点;

题目中有m条查询,每次查询都改变其中一个字符,如果直接暴力会被T的,所以要动动脑子了;

仔细观察会发现在一段连续的n个点中,需要进行n-1个操作使得n个点合并为一个点,那么假设现在有m段连续的点,其中每段的点的个数为a1,a2,a3...am,共计n个点;则需要进行的操作次数为(a1-1)+(a2-1)+(a3-1)+......+(am-1)=a1+a2+a3+......+am-m=n-m;

可知,最终结果应为点的总个数减去区间数;

代码奉上:

#include <iostream>using namespace std;int main(){int n, m;cin >> n >> m;string s;cin >> s;int cnt, block, len=s.size();//cnt表示'.'的总数,block表示区间数;cnt=block=0;bool flag=false;for(int i=0; i<len; i++){if(s[i]=='.') cnt++;if(s[i]=='.'&&!flag){block++;flag=true;}if(s[i]!='.') flag=false;}int x;string op;for(int i=0; i<m; i++){cin >> x >> op;x--;            //题目中字符串由1开始计数;//只有给出的字符与原字符不同时结果才会改变;                if(s[x]=='.'){if(op[0]!='.'){s[x]=op[0];//改变原字符串;cnt--;if(x==0&&s[x+1]!='.') block--;else if(x==len-1&&s[x-1]!='.') block--;else if(x<len-1 && x>0){if(s[x-1]=='.'&&s[x+1]=='.') block++;else if(s[x-1]!='.'&&s[x+1]!='.') block--; }}}else{if(op[0]=='.'){s[x]=op[0];cnt++;if(x==0&&s[x+1]!='.') block++;else if(x==len-1&&s[x-1]!='.') block++;else if(x>0&&x<len-1){if(s[x+1]=='.'&&s[x-1]=='.') block--;else if(s[x+1]!='.'&&s[x-1]!='.') block++;}}}//cout << "cnt: " << cnt << "  block: " << block << endl;cout << cnt-block << endl;}return 0;}












原创粉丝点击