题意:n个人站成一排,初始时刻每个人手中都有一个图案,可能是石头,剪刀,布3个中的1种,之后会随机选取相邻的两个人玩石头剪刀布的游戏,输的人会离开(如果两个人图案相同,则随机选择一个人离开)。执行(n-1)次操作剩下的最后一个人是冠军,问有多少个人可能成为最后的冠军?并且还有m次修改,每次修改会改变某个人的图案,并且要输出修改后可能成为冠军的人数。

思路:为了方便叙述,我们把石头,剪刀,布记为0,1,2,并且0大于2,2小于0。通过观察,我们很容易可以发现如果一个人可能成为冠军必须满足以下两个条件之一:

1:这个人的左右两边没有人的图案比他大(左边或右边没人也看作没人比他大)。

2:这个人的某一边既有比他大的,也有比他小的。

稍微解释一下条件2:这边比他大的图案都有可能被这这比他小的图案吃掉,因为这个比他小的图案比比他大的图案大。比如:0 1 2 。虽然1比0大,但是有比0小的2的存在,2可以把1吃掉。

把条件1和条件2合并一下,只要两边都有小于它的图案,无论什么情况都肯成为冠军。假设该数为x,比他小的数为y,最左端y的位置记为l,最右端的记为r,则[l,r]中所有x都可能成为冠军。

对于剩余的情况,比如左端中没在[l.r]中的数x,可能成为冠军的情况只能是左端没有大于他的数,右端同理。

于是我们可以用树状数组查询区间的个数,set维护每个数的位置。

代码:

#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
const int maxn=200010;
int n,m;
struct BIT{
int c[maxn]; void add(int x,int y){
for(;x<=n;x+=lowbit(x))c[x]+=y;
} int ask(int x){
int ans=0;
for(;x;x-=lowbit(x))ans+=c[x];
return ans;
} int query(int l,int r){
return ask(r)-ask(l-1);
}
};
BIT b[3];
set<int> s[3];
map<char,int> mp;
int a[maxn];
char str[maxn];
int solve(void){
int ans=0;
for(int i=0;i<3;i++){
if(s[(i+1)%3].empty()){
ans+=s[i].size();
continue;
}
if(s[(i+2)%3].empty())continue;
int l1=*(s[(i+2)%3].begin()),r1=*(--s[(i+2)%3].end());
ans+=b[i].query(l1,r1);
int l2=*(s[(i+1)%3].begin()),r2=*(--s[(i+1)%3].end());
ans+=b[i].query(1,min(l1,l2)-1);
ans+=b[i].query(max(r1,r2)+1,n);
}
return ans;
}
int main(){
mp['R']=0,mp['P']=1,mp['S']=2;
scanf("%d%d",&n,&m);
scanf("%s",str+1);
for(int i=1;i<=n;i++){
a[i]=mp[str[i]];
b[a[i]].add(i,1);
s[a[i]].insert(i);
}
printf("%d\n",solve());
for(int i=1;i<=m;i++){
int x;
scanf("%d%s",&x,str+1);
b[a[x]].add(x,-1);
s[a[x]].erase(x);
a[x]=mp[str[1]];
b[a[x]].add(x,1);
s[a[x]].insert(x);
printf("%d\n",solve());
}
}

  

Codeforces #528 Div2 F (1087F) Rock-Paper-Scissors Champion 树状数组+set的更多相关文章

  1. Codeforces Round #300 F - A Heap of Heaps (树状数组 OR 差分)

    F. A Heap of Heaps time limit per test 3 seconds memory limit per test 512 megabytes input standard ...

  2. CodeForces 122G Lucky Array(一脸懵逼的树状数组)

    Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal re ...

  3. 北邮校赛 F. Gabriel's Pocket Money(树状数组)

    F. Gabriel's Pocket Money 2017- BUPT Collegiate Programming Contest - sync 时间限制 2000 ms 内存限制 65536 K ...

  4. Codeforces Beta Round #79 (Div. 1 Only) B. Buses 树状数组

    http://codeforces.com/contest/101/problem/B 给定一个数n,起点是0  终点是n,有m两车,每辆车是从s开去t的,我们只能从[s,s+1,s+2....t-1 ...

  5. Codeforces Round #413 (Div1 + Div. 2) C. Fountains(树状数组维护最大值)

    题目链接:https://codeforces.com/problemset/problem/799/C 题意:有 c 块硬币和 d 块钻石,每种喷泉消耗硬币或钻石中的一种,每个喷泉有一个美丽值,问建 ...

  6. Codeforces 899 F. Letters Removing (二分、树状数组)

    题目链接:Letters Removing 题意: 给你一个长度为n的字符串,给出m次操作.每次操作给出一个l,r和一个字符c,要求删除字符串l到r之间所有的c. 题解: 看样例可以看出,这题最大的难 ...

  7. Codeforces Round #368 (Div. 2) E. Garlands 二维树状数组 暴力

    E. Garlands 题目连接: http://www.codeforces.com/contest/707/problem/E Description Like all children, Ale ...

  8. Codeforces Beta Round #12 (Div 2 Only) D. Ball 树状数组查询后缀、最值

    http://codeforces.com/problemset/problem/12/D 这里的BIT查询,指的是查询[1, R]或者[R, maxn]之间的最值,这样就够用了. 设三个权值分别是b ...

  9. Codeforces Round #216 (Div. 2) E. Valera and Queries 树状数组 离线处理

    题意:n个线段[Li, Ri], m次询问, 每次询问由cnt个点组成,输出包含cnt个点中任意一个点的线段的总数. 由于是无修改的,所以我们首先应该往离线上想, 不过我是没想出来. 首先反着做,先求 ...

随机推荐

  1. MySQL 基础数据类型优化(如何选择数据类型)

    前言:      最近在看高性能 MySQL,记录写学习笔记:           高性能 MySQL 学习笔记(二) Schema与数据类型优化      笔记核心内容:MySQL 如何选择正确的数 ...

  2. swagger 在apache CXF 中的使用——JAX-RS Swagger2Feature

    The CXF Swagger2Feature allows you to generate Swagger 2.0 documents from JAX-RS service endpoints w ...

  3. Linux tar命令总结

    压缩 tar –cvf jpg.tar *.jpg  将目录里所有jpg文件打包成tar.jpg tar –czf jpg.tar.gz *.jpg   将目录里所有jpg文件打包成jpg.tar后, ...

  4. Tomcat_总结_01_tomcat环境搭建

    一.准备条件 1.安装jdk 二.安装tomcat 1.下载tomcat 去官网下载  64-bit Windows zip  版本的tomcat,并解压 https://tomcat.apache. ...

  5. LeetCode Find Mode in Binary Search Tree

    原题链接在这里:https://leetcode.com/problems/find-mode-in-binary-search-tree/#/description 题目: Given a bina ...

  6. 普通平衡树 - Treap

    怕被学弟怼 : "你的博客上没有Treap模板啊?" #include <cstdio> #include <cstring> #include <a ...

  7. 在winform下实现左右布局多窗口界面的方法(一)

    在web页面上我们可以通过frameset,iframe嵌套框架很容易实现各种导航+内容的布局界面,而在winform.WPF中实现其实也很容易,通过本文给大家介绍在winform下实现左右布局多窗口 ...

  8. Linux 终端 忽略大小写

    忘了在哪里看到的了,记录一下. 在-/.inputrc中加入一行 set completion-ignore-case on 搞定! 这样在终端输入.补全时就忽略大小写了.当然,Linux本身还是区分 ...

  9. 第五篇 Nginx的简单配置

    先安装: sudo apt-get install nginx php5-fpm 我是在新安装的Ubuntu13上测试通过的,真的只安装这两个东西就够了. 然后编辑配置文件. sudo gedit / ...

  10. linux环境下搭建redis

    1. 官网下载安装包,然后解压,或者直接从github上pull下来. git clone https://github.com/antirez/redis.git 2. 确保linux环境上已安装g ...