hihocoder #1058 Combination Lock
描述
Finally, you come to the interview room. You know that a Microsoft interviewer is in the room though the door is locked. There is a combination lock on the door. There are N rotators on the lock, each consists of 26 alphabetic characters, namely, 'A'-'Z'. You need to unlock the door to meet the interviewer inside. There is a note besides the lock, which shows the steps to unlock it.
Note: There are M steps totally; each step is one of the four kinds of operations shown below:
Type1: CMD 1 i j X: (i and j are integers, 1 <= i <= j <= N; X is a character, within 'A'-'Z')
This is a sequence operation: turn the ith to the jth rotators to character X (the left most rotator is defined as the 1st rotator)
For example: ABCDEFG => CMD 1 2 3 Z => AZZDEFG
Type2: CMD 2 i j K: (i, j, and K are all integers, 1 <= i <= j <= N)
This is a sequence operation: turn the ith to the jth rotators up K times ( if character A is turned up once, it is B; if Z is turned up once, it is A now. )
For example: ABCDEFG => CMD 2 2 3 1 => ACDDEFG
Type3: CMD 3 K: (K is an integer, 1 <= K <= N)
This is a concatenation operation: move the K leftmost rotators to the rightmost end.
For example: ABCDEFG => CMD 3 3 => DEFGABC
Type4: CMD 4 i j(i, j are integers, 1 <= i <= j <= N):
This is a recursive operation, which means:
If i > j:
Do Nothing
Else:
CMD 4 i+1 j
CMD 2 i j 1For example: ABCDEFG => CMD 4 2 3 => ACEDEFG
输入
1st line: 2 integers, N, M ( 1 <= N <= 50000, 1 <= M <= 50000 )
2nd line: a string of N characters, standing for the original status of the lock.
3rd ~ (3+M-1)th lines: each line contains a string, representing one step.
输出
One line of N characters, showing the final status of the lock.
提示
Come on! You need to do these operations as fast as possible.
- 样例输入
-
7 4
ABCDEFG
CMD 1 2 5 C
CMD 2 3 7 4
CMD 3 3
CMD 4 1 7 - 样例输出
- HIMOFIN
Analysis:
Implementation:
#include <bits/stdc++.h>
using namespace std; const int N(5e4+);
int same[N<<], rot[N<<], delta[N<<], inc[N<<];
char s[N]; void build(int id, int L, int R){
if(L==R){same[id]=s[L]-'A'; return;}
int mid=(L+R)>>;
same[id]=-;
build(id<<, L, mid);
build(id<<|, mid+, R);
} void CLEAR(int id, int v){
same[id]=v, rot[id]=delta[id]=inc[id]=;
} void push_rot(int s, int f){
rot[s]+=rot[f], rot[s]%=;
} void push_inc(int s, int f, int d){
delta[s]+=d, inc[s]+=inc[f], delta[s]%=, inc[s]%=;
} void push_down(int id, int L, int R){
int ls=id<<, rs=ls|;
if(~same[id]) CLEAR(ls, same[id]), CLEAR(rs, same[id]), same[id]=-;
if(rot[id]) push_rot(ls, id), push_rot(rs, id), rot[id]=;
int mid=(R+L)>>, t=delta[id]+(mid+-L)*inc[id];
push_inc(ls, id, delta[id]), push_inc(rs, id, t%), delta[id]=inc[id]=;
} int query(int id, int L, int R, int p){
if(~same[id]) return (same[id]+rot[id]+delta[id]+(p-L)*inc[id])%;
push_down(id, L, R); //error-prone
int mid=(L+R)>>;
if(p<=mid) return query(id<<, L, mid, p);
return query(id<<|, mid+, R, p);
} void SET(int id, int L, int R, int l, int r, int v){
if(l<=L && R<=r){
CLEAR(id, v);
return;
}
push_down(id, L, R);
int mid=(L+R)>>;
if(l<=mid) SET(id<<, L, mid, l, r, v);
if(r>mid) SET(id<<|, mid+, R, l, r, v);
} void ROTATE(int id, int L, int R, int l, int r, int v){
if(l<=L && R<=r){rot[id]+=v, rot[id]%=; return;}
push_down(id, L, R);
int mid=(L+R)>>;
if(l<=mid) ROTATE(id<<, L, mid, l, r, v);
if(r>mid) ROTATE(id<<|, mid+, R, l, r, v);
} void INC_SHIFT(int id, int L, int R, int l, int r, int v){
if(l<=L && R<=r){
delta[id]+=v+L-l; //error-prone
inc[id]+=;
delta[id]%=, inc[id]%=;
return;
}
push_down(id, L, R);
int mid=(L+R)>>;
if(l<=mid) INC_SHIFT(id<<, L, mid, l, r, v); //error-prone
if(r>mid) INC_SHIFT(id<<|, mid+, R, l, r, v);
} int main(){
int n, m;
cin>>n>>m>>s;
build(, , n-);
char ch;
int shift=; //number of left shift
for(int t, l, r, k; m--; ){
scanf("%*s%d", &t);
if(t!=) cin>>l>>r, l--, r--, l=(l+shift)%n, r=(r+shift)%n;
if(t==){
cin>>ch, k=ch-'A'; //cin ignores leading spaces.
if(l<=r) SET(, , n-, l, r, k);
else SET(, , n-, l, n-, k), SET(, , n-, , r, k);
}
else if(t==){
cin>>k;
if(l<=r) ROTATE(, , n-, l, r, k);
else ROTATE(, , n-, l, n-, k), ROTATE(, , n-, , r, k);
}
else if(t==){
cin>>k, shift+=k, shift%=n;
}
else{
if(l<=r) INC_SHIFT(, , n-, l, r, );
else INC_SHIFT(, , n-, l, n-, ), INC_SHIFT(, , n-, , r, n-l+);
}
}
for(int i=; i<n; i++) putchar(query(, , n-, (i+shift)%n)+'A');
puts("");
return ;
}
实现细节:
这道题代码量相对大一些,而且有些地方容易想不清楚。
先总结一下线段树:
线段树是用来维护区间上的修改(亦称 更新/modify/update)与查询(query)的。修改与查询都可分成两类:点修改,区间修改;点查询,区间查询。
其中区间修改往往要用到 lazy-tag 技巧。线段树节点维护的所有atrribute都是关于这个节点所对应的区间的,广义而言,都可看作区间的函数
\[f([L, R])\] 这些 attribute 记录的信息可分为两类,一类是该区间的某种属性(properties),另一类是对此区间(已经)进行的某些操作(operations),或者说该区间经历 (expierenced)的某些操作。
再说说这道题的实现:
线段树的每个节点所需的 atrribute,除了 Analysis 中提到的 delta, inc(用来记录该区间经历的CMD 4操作)之外,还有
- same,用来记录该区间经历的CMD 1操作,我们用0~25代表'A'~'Z';
- rot,用来记录该区间所经历的CMD 2操作;
CMD 1操作会将该区间已经历的所有其他操作全部覆盖(清空)。
hihocoder #1058 Combination Lock的更多相关文章
- Combination Lock
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Finally, you come to the interview room. You know that a Micr ...
- 贪心 Codeforces Round #301 (Div. 2) A. Combination Lock
题目传送门 /* 贪心水题:累加到目标数字的距离,两头找取最小值 */ #include <cstdio> #include <iostream> #include <a ...
- Codeforces Round #301 (Div. 2) A. Combination Lock 暴力
A. Combination Lock Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/540/p ...
- Hiho----微软笔试题《Combination Lock》
Combination Lock 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Finally, you come to the interview room. You ...
- CF #301 A :Combination Lock(简单循环)
A :Combination Lock 题意就是有一个密码箱,密码是n位数,现在有一个当前箱子上显示密码A和正确密码B,求有A到B一共至少需要滚动几次: 简单循环:
- hihocoder-第六十一周 Combination Lock
题目1 : Combination Lock 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Finally, you come to the interview roo ...
- A - Combination Lock
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description Scroog ...
- HDU 3104 Combination Lock(数学题)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3104 Problem Description A combination lock consists ...
- 洛谷 P2693 [USACO1.3]号码锁 Combination Lock
P2693 [USACO1.3]号码锁 Combination Lock 题目描述 农夫约翰的奶牛不停地从他的农场中逃出来,导致了很多损害.为了防止它们再逃出来,他买了一只很大的号码锁以防止奶牛们打开 ...
随机推荐
- Linux下CGroup使用说明梳理
CGroup 介绍CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制.记录.隔离进程组 (process groups) 所使用的物力资源 (如 cpu m ...
- 第二章 下山遇虎(@helper)
@helper方法定义 使用@helper关键字可以定义一个方法,这样就可以在页面中调 用这个方法了,和C#中的方法一样.在页面中定义的方法可以访问ViewBag,HttpContext等等页面的属性 ...
- 客户端缓存(Client Cache)
通常在服务器端大家都已经做了很多缓存的工作,ASP.NET CACHE也好MemeryCache也好却总是忽略了客户端缓存. 因为大家都知道不管哪个client都会缓存已经访问过的站点,但是浏览器缓存 ...
- C语言 文件操作11--文件函数再讲 fseek()和ftell()
//文件函数再讲 //fseek(),ftell(), #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdl ...
- dos常用命令
进入终端 首先具备一个控制台(命令行提示符窗口)用于输入dos命令: 打开一个控制台的方式: 方式一:开始-------> 所有程序--------->附件----------->命 ...
- WCF与ASMX Web服务差异比较[译]
First of all, it needs to understand that WCF Service provides all the capabilities of .NET web serv ...
- 2016动作短片《全境封锁:特工起源》HD720P.英语中字
导演: 德文·格雷厄姆主演: Matt Lynch / Sasha Andreev / Amanda Day类型: 动作 / 短片制片国家/地区: 美国语言: 英语上映日期: 2016-01-19片长 ...
- python数字图像处理(2):图像的读取、显示与保存
skimage提供了io模块,顾名思义,这个模块是用来图片输入输出操作的.为了方便练习,也提供一个data模块,里面嵌套了一些示例图片,我们可以直接使用. 引入skimage模块可用: from sk ...
- 使用Windows Live Writer发布日志
前言 Windows Live Writer是非常不错的一个日志发布工具,支持本地写文章,然后通过点击一个按钮就发布到网站上,如果借助插件,还可以同时发布到多个博客网站,功能非常强大,很多博友认识她之 ...
- Linux第三次学习笔记
#信息的表示和处理 三种重要的数字表示 1. 无符号数编码: 基于传统的二进制表示法,表示大于或者等于零的数字. 2. 补码编码: 表示有符号数整数的最常见的方式,有符号数就是只可 以为正或者为负的数 ...