Codeforces #528 Div2 F (1087F) Rock-Paper-Scissors Champion 树状数组+set
题意: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的更多相关文章
- 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 ...
- CodeForces 122G Lucky Array(一脸懵逼的树状数组)
Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal re ...
- 北邮校赛 F. Gabriel's Pocket Money(树状数组)
F. Gabriel's Pocket Money 2017- BUPT Collegiate Programming Contest - sync 时间限制 2000 ms 内存限制 65536 K ...
- 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 ...
- Codeforces Round #413 (Div1 + Div. 2) C. Fountains(树状数组维护最大值)
题目链接:https://codeforces.com/problemset/problem/799/C 题意:有 c 块硬币和 d 块钻石,每种喷泉消耗硬币或钻石中的一种,每个喷泉有一个美丽值,问建 ...
- Codeforces 899 F. Letters Removing (二分、树状数组)
题目链接:Letters Removing 题意: 给你一个长度为n的字符串,给出m次操作.每次操作给出一个l,r和一个字符c,要求删除字符串l到r之间所有的c. 题解: 看样例可以看出,这题最大的难 ...
- Codeforces Round #368 (Div. 2) E. Garlands 二维树状数组 暴力
E. Garlands 题目连接: http://www.codeforces.com/contest/707/problem/E Description Like all children, Ale ...
- Codeforces Beta Round #12 (Div 2 Only) D. Ball 树状数组查询后缀、最值
http://codeforces.com/problemset/problem/12/D 这里的BIT查询,指的是查询[1, R]或者[R, maxn]之间的最值,这样就够用了. 设三个权值分别是b ...
- Codeforces Round #216 (Div. 2) E. Valera and Queries 树状数组 离线处理
题意:n个线段[Li, Ri], m次询问, 每次询问由cnt个点组成,输出包含cnt个点中任意一个点的线段的总数. 由于是无修改的,所以我们首先应该往离线上想, 不过我是没想出来. 首先反着做,先求 ...
随机推荐
- 论文笔记 — MatchNet: Unifying Feature and Metric Learning for Patch-Based Matching
论文:https://github.com/ei1994/my_reference_library/tree/master/papers 本文的贡献点如下: 1. 提出了一个新的利用深度网络架构基于p ...
- python3中的unicode_escape
一. 响应的两种方式 在使用python3的requests模块时,发现获取响应有两种方式 其一,为文本响应内容, r.text 其二,为二进制响应内容,r.content 在<Python学习 ...
- Codeforces Round #435 (Div. 2) c+d
C:给n和k要求,找出n个不同的数,使得亦或起来等于k 可以先预处理从1到1e5,找亦或起来等于(11111111111111111)(二进制)的所有对数,然后四个一起亦或就是0了,再和k亦或 可以看 ...
- 用系统工具sxstrace检查缺少的VC运行时组件
在管理员运行的命令提示符中输入sxstrace获得如下帮助: C:\>sxstrace WinSxs Tracing Utility. Usage: SxsTrace [Options] Opt ...
- The CHECK_POLICY and CHECK_EXPIRATION options cannot be turned OFF when MUST_CHANGE is ON. (Microsoft SQL Server,错误: 15128)
记录下 The CHECK_POLICY and CHECK_EXPIRATION options cannot be turned OFF when MUST_CHANGE is ON. (Micr ...
- 动态加载CSS,JS文件
var Head = document.getElementsByTagName('head')[0],style = document.createElement('style'); //文件全部加 ...
- php中实现将姓名拆分为姓氏和名字
之前有分享了用javascript在客户端进行姓名拆分的方法,后应项目需要,又用PHP实现了,贴出来 跟大家分享交流: /** * 把全名拆分为姓氏和名字 * @param string $fulln ...
- Linux-监控与安全运维之Nagios
1. Nagios 简介是一个开源软件,可以监控网络设备网络流量.Linux/windows主机状态,甚至可以监控打印机它可以运行在Linux上或windows上基于浏览器的web界面方便运维人员查看 ...
- main函数的参数的用法
说明:main函数的参数的用法源代码: #include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[] ...
- BZOJ- 3142:数列 (数学)
题意:给出N,K,M,P.求有多少长度为K的序列A,满足:(1)首项为正整数:(2)递增数列:(3)相邻两项的差小于等于m:(4)最后一个数小于等于N. 思路:根据差分来算数量. #include&l ...