C. Replacement
Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://codeforces.com/contest/570/problem/C

Description

Daniel has a string s, consisting of lowercase English letters and period signs (characters '.'). Let's define the operation of replacementas 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

10 3
.b..bz....
1 h
3 c
9 f

Sample Output

4
3
1

HINT

题意

给你一个字符串,然后每两个点可以变成一个点

然后有m次修改操作,每次可以修改一个位置的字符

然后问你修改之后,需要多少次操作,把所有的点,都变成连续的一个点

题解

我比较蠢,我用的线段树,太蠢了

正解不超过30行,几个if就好了……

维护的是每一个pos的左边的字母和右边的字母位置

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std; #define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=; struct node
{
int lft,rht;
int lmx,rmx;
int len(){return rht-lft+;}
int mid(){return MID(lft,rht);}
void init(){lmx=rmx=len();}
void fun(int valu)
{
if(valu==-) lmx=rmx=;
else lmx=rmx=;
}
}; int n,m; struct Segtree
{
node tree[N*];
void up(int ind)
{
tree[ind].lmx=tree[LL(ind)].lmx;
tree[ind].rmx=tree[RR(ind)].rmx;
if(tree[LL(ind)].lmx==tree[LL(ind)].len())
tree[ind].lmx+=tree[RR(ind)].lmx;
if(tree[RR(ind)].rmx==tree[RR(ind)].len())
tree[ind].rmx+=tree[LL(ind)].rmx;
}
void build(int lft,int rht,int ind)
{
tree[ind].lft=lft,tree[ind].rht=rht;
tree[ind].init();
if(lft!=rht)
{
int mid=tree[ind].mid();
build(lft,mid,LL(ind));
build(mid+,rht,RR(ind));
}
}
void updata(int pos,int ind,int valu)
{
if(tree[ind].lft==tree[ind].rht) tree[ind].fun(valu);
else
{
int mid=tree[ind].mid();
if(pos<=mid) updata(pos,LL(ind),valu);
else updata(pos,RR(ind),valu);
up(ind);
}
}
void query(int pos,int ind,int& x,int& y)
{
if(tree[ind].lft==tree[ind].rht)
{
if(tree[ind].lmx==) x=y=tree[ind].lft;
else x=y=;
}
else
{
int mid=tree[ind].mid();
if(pos<=mid) query(pos,LL(ind),x,y);
else query(pos,RR(ind),x,y);
if(tree[LL(ind)].rht==y) y+=tree[RR(ind)].lmx;
if(tree[RR(ind)].lft==x) x-=tree[LL(ind)].rmx;
}
}
}seg;
char s[N];
int vis[N];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%s",s+);
seg.build(,n+,);
int len=strlen(s+);
int ans=;
int tmp=;
seg.updata(n+,,-);
for(int i=;i<=len;i++)
{
if(s[i]=='.')
tmp++;
else
{
if(tmp!=)
ans+=(tmp-);
tmp=;
seg.updata(i,,-);
vis[i]=;
}
}
if(tmp!=)
ans+=(tmp-);
while(m--)
{
char cmd[];
int pos,st,ed;
scanf("%d",&pos);
scanf("%s",&cmd);
if(cmd[]!='.')
{
if(vis[pos]==)
printf("%d\n",ans);
else
{
vis[pos]=; seg.query(pos,,st,ed);
ans-=(ed-st);
seg.updata(pos,,-);
seg.query(pos+,,st,ed);
ans+=(ed-st);
if(pos-!=)
{
seg.query(pos-,,st,ed);
ans+=(ed-st);
}
printf("%d\n",ans);
} }
else
{
if(vis[pos]==)
printf("%d\n",ans);
else
{
vis[pos]=;
seg.query(pos+,,st,ed);
ans-=(ed-st);
if(pos-!=)
{
seg.query(pos-,,st,ed);
ans-=(ed-st);
}
seg.updata(pos,,);
seg.query(pos,,st,ed);
ans+=(ed-st);
printf("%d\n",ans); }
}
}
}
return ;
}

Codeforces Codeforces Round #316 (Div. 2) C. Replacement 线段树的更多相关文章

  1. Codeforces Round #603 (Div. 2) E. Editor 线段树

    E. Editor The development of a text editor is a hard problem. You need to implement an extra module ...

  2. Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路

    B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...

  3. Codeforces Round #765 Div.1 F. Souvenirs 线段树

    题目链接:http://codeforces.com/contest/765/problem/F 题意概述: 给出一个序列,若干组询问,问给出下标区间中两数作差的最小绝对值. 分析: 这个题揭示着数据 ...

  4. 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路

    B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...

  5. Codeforces Codeforces Round #316 (Div. 2) C. Replacement set

    C. Replacement Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/570/proble ...

  6. Codeforces Round #316 (Div. 2) C. Replacement

    题意:给定一个字符串,里面有各种小写字母和' . ' ,无论是什么字母,都是一样的,假设遇到' . . ' ,就要合并成一个' .',有m个询问,每次都在字符串某个位置上将原来的字符改成题目给的字符, ...

  7. Codeforces Round #316 (Div. 2) C. Replacement(线段树)

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

  8. Codeforces Round #316 (Div. 2C) 570C Replacement

    题目:Click here 题意:看一下题目下面的Note就会明白的. 分析:一开始想的麻烦了,用了树状数组(第一次用)优化,可惜没用. 直接判断: #include <bits/stdc++. ...

  9. Codeforces Round #316 (Div. 2) C Replacement 扫描法

    先扫描一遍得到每个位置向后连续的'.'的长度,包含自身,然后在扫一遍求出初始的合并次数. 对于询问,只要对应位置判断一下是不是'.',以及周围的情况. #include<bits/stdc++. ...

随机推荐

  1. 【转】linux下a.out >outfile 2>&1重定向问题

    原文网址:http://blog.chinaunix.net/uid-25909722-id-2912890.html 转自:http://blog.chinaunix.net/space.php?u ...

  2. 130道ASP.NET面试题

    转:http://boke.25k5.com/kan88569.html 1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . privat ...

  3. PostgreSQL 8.4.1

    PHP100资讯:PostgreSQL 是一种对象-关系型数据库管理系统(ORDBMS),也是目前功能最强大.特性最丰富和最复杂的自由软件数据库系统.它起源于伯克利(BSD)的数据库研究计划,目前是最 ...

  4. TabWidget/TabHost的两种使用方法

    1.概念 盛放Tab的容器就是TabHost.TabHost的实现有两种方式: 第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost.各个Tab ...

  5. <转>Python 多线程的单cpu与cpu上的多线程的区别

    你对Python 多线程有所了解的话.那么你对python 多线程在单cpu意义上的多线程与多cpu上的多线程有着本质的区别,如果你对Python 多线程的相关知识想有更多的了解,你就可以浏览我们的文 ...

  6. 《Python核心编程》 第四章 Python对象- 课后习题

    练习 4-1. Python对象.与所有Python对象有关的三个属性是什么?请简单的描述一下. 答:身份.类型和值: 身份:每一个对象都有一个唯一的身份标识自己,可以用id()得到.  类型:对象的 ...

  7. RockMongo安装使用笔记

    下载nginx最新版本下载PHP,5.X版本即可,非线程安全的的,因为nginx用的是fastcgi下载rockmongo最新版本下载php_mongo组件 在rockmongo里的readme里有下 ...

  8. qt 获取天气的接口

    博客来源:http://blog.csdn.net/lzqwebsoft/article/details/7054045 网站api接口:http://smart.weather.com.cn/wzf ...

  9. 根据关键词获取进程ID然后杀掉进程

    例如需要杀掉监听进程,如下: [oracle@kel ~]$ ps -ef|grep lsnr oracle 4973 1 1 19:40 ? 00:00:00 /home/oracle/produc ...

  10. Python中的__init__,__call__

    __init__函数 当一个类实例被创建时, __init__() 方法会自动执行,在类实例创建完毕后执行,类似构建函数.__init__() 可以被当成构建函数,不过不象其它语言中的构建函数,它并不 ...