D. Selection

Time Limit: 1 Sec

Memory Limit: 256 MB

题目连接

http://codeforces.com/gym/100114

Description

When selecting files in an application dialog, Vasya noted that he can get the same selection in different ways. A simple mouse click selects a single file (the existing selection is discarded). A shift-click is used to select a range of files from the file clicked last time to the current file (the existing selection is discarded). Finally, a control-click is used to invert the selection state of a single file. Consider a sequence of actions. First we select file #5 simply by clicking it. Then, shift-clicking file #10 we get the following selection: #5, #6, #7, #8, #9, #10. If after that we control-click files #7 and #3 then we will have files #3, #5, #6, #8, #9, and #10 selected. Shift-clicking file #1 we select files #1, #2, and #3 (last time we clicked file #3, and the previous selection is gone). Vasya is wondering, what the minimum number of clicks will be, to make a certain selection from the list of files. Write a program to determine the optimal way of making the required selection. If there are several minimal solutions, any of them is considered correct. Example. Suppose we are to select files #2, #5, #6, #8, #9 from a list of 10 files. A possible optimal solution will include the following clicks: 5, Shift+9, Ctrl+2, Ctrl+7.

Input

The first line contains an integer n, the number of files in the list. The following line contains n characters defining the required selection. If i-th file is to be selected then there is an asterisk (“*”) in position i, and a dot (“.”) otherwise.

Output

The first line of the output file must contain a single integer k – the minimum number of clicks necessary to make the given selection. The following k lines must define the way to make such a selection. Each line should contain the number of file to be clicked on the corresponding step, and a prefix “Ctrl+” or “Shift+” (without quotation marks) where necessary.

Sample Input

10 .*..**.**.

Sample Output

4 5 Shift+9 Ctrl+2 Ctrl+7

HINT

1 ≤ n ≤ 105 .

题意

有3种操作

1.光标移动到X

2.shift X,直接选择从光标到X的位置

3.选择X,如果X已经被选中,那就取消X的选中状态

问你最少多少步,可以选择所有的*

并且把步骤输出

题解:

注意,只能shift 1次,所以直接扫一遍就好了

跑一遍线段树维护的DP,表示到这儿,所需要的最小代价是多少

代码:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <vector>
  7. #include <stack>
  8. #include <map>
  9. #include <set>
  10. #include <queue>
  11. #include <iomanip>
  12. #include <string>
  13. #include <ctime>
  14. #include <list>
  15. #include <bitset>
  16. typedef unsigned char byte;
  17. #define pb push_back
  18. #define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
  19. #define local freopen("in.txt","r",stdin)
  20. #define pi acos(-1)
  21.  
  22. using namespace std;
  23. const int maxn = 1e5 + ;
  24. char str[maxn];
  25. int length , sum[maxn], dp[maxn];
  26. vector<int>Q,Q2;
  27.  
  28. struct operation
  29. {
  30. int x;
  31. int type;
  32. };
  33.  
  34. operation nxt[maxn];
  35.  
  36. struct QueryData
  37. {
  38. int minv , minpos;
  39. QueryData(int minv , int minpos)
  40. {
  41. this->minv = minv , this->minpos = minpos;
  42. }
  43. };
  44.  
  45. typedef int SgTreeDataType;
  46. struct treenode
  47. {
  48. int L , R ;
  49. SgTreeDataType minv , minpos;
  50. void updata(SgTreeDataType v)
  51. {
  52. minv = v;
  53. }
  54. };
  55.  
  56. treenode tree[maxn * ];
  57.  
  58. inline void push_up(int o)
  59. {
  60. if(tree[o*].minv > tree[o*+].minv)
  61. {
  62. tree[o].minv = tree[o*+].minv;
  63. tree[o].minpos = tree[o*+].minpos;
  64. }
  65. else
  66. {
  67. tree[o].minv = tree[o*].minv;
  68. tree[o].minpos = tree[o*].minpos;
  69. }
  70. }
  71.  
  72. inline void build_tree(int L , int R , int o)
  73. {
  74. tree[o].L = L , tree[o].R = R,tree[o].minv = << , tree[o].minpos = ;
  75. if(L == R) tree[o].minpos = L;
  76. if (R > L)
  77. {
  78. int mid = (L+R) >> ;
  79. build_tree(L,mid,o*);
  80. build_tree(mid+,R,o*+);
  81. }
  82. }
  83.  
  84. inline void updata(int QL,int QR,SgTreeDataType v,int o)
  85. {
  86. int L = tree[o].L , R = tree[o].R;
  87. if (QL <= L && R <= QR) tree[o].updata(v);
  88. else
  89. {
  90. int mid = (L+R)>>;
  91. if (QL <= mid) updata(QL,QR,v,o*);
  92. if (QR > mid) updata(QL,QR,v,o*+);
  93. push_up(o);
  94. }
  95. }
  96.  
  97. inline QueryData query(int QL,int QR,int o)
  98. {
  99. int L = tree[o].L , R = tree[o].R;
  100. if (QL <= L && R <= QR) return QueryData(tree[o].minv,tree[o].minpos);
  101. else
  102. {
  103. int mid = (L+R)>>;
  104. if (QL <= mid && QR > mid)
  105. {
  106. QueryData a = query(QL,QR,*o);
  107. QueryData b = query(QL,QR,*o+);
  108. if(a.minv < b.minv) return a;
  109. else return b;
  110. }
  111. else if (QL <= mid) return query(QL,QR,*o);
  112. else return query(QL,QR,*o+);
  113. }
  114. }
  115.  
  116. void initiation()
  117. {
  118. memset( dp , , sizeof(dp));
  119. scanf("%d%s",&length,str+);sum[] = ;
  120. for(int i = ; i <= length ; ++ i)
  121. {
  122. sum[i] = sum[i-];
  123. if(str[i] == '*')
  124. {
  125. Q.push_back(i);
  126. }
  127. else
  128. {
  129. sum[i] ++ ;
  130. Q2.push_back(i);
  131. }
  132. }
  133. }
  134.  
  135. void solve()
  136. {
  137. int sz = Q.size();
  138. int ansL = Q[],ansR = Q[],ans=sz;
  139. build_tree( , sz - , );
  140. for(int i = ; i < sz ; ++ i) updata( i , i , sum[Q[i]] - i , );
  141. for(int i = ; i < sz - ; ++ i)
  142. {
  143. QueryData y = query( i + , sz - , );
  144. int newans = i + + sz + y.minv - sum[Q[i]];
  145. if(newans < ans)
  146. {
  147. ans = newans;
  148. ansL = i;
  149. ansR = y.minpos;
  150. }
  151. }
  152. printf("%d\n",ans);
  153. if(ansL != ansR)
  154. {
  155. printf("%d\n",Q[ansL]);
  156. printf("Shift+%d\n",Q[ansR]);
  157. for(int i = ; i < sz ; ++ i) if(i < ansL || i > ansR) printf("Ctrl+%d\n",Q[i]);
  158. for(int i = ; i < Q2.size() ; ++ i) if( Q2[i] < Q[ansR] && Q2[i] > Q[ansL]) printf("Ctrl+%d\n",Q2[i]);
  159. }
  160. else
  161. {
  162. printf("%d\n",Q[]);
  163. for(int i = ; i < sz ; ++ i) printf("Ctrl+%d\n",Q[i]);
  164. }
  165. }
  166.  
  167. int main(int argc,char *argv[])
  168. {
  169. freopen("input.txt","r",stdin);
  170. freopen("output.txt","w",stdout);
  171. initiation();
  172. if(Q.size() == ) printf("0\n");
  173. else if(Q.size() == ) printf("1\n%d\n",Q[]);
  174. else if(Q.size() == ) printf("2\n%d\nCtrl+%d\n",Q[],Q[]);
  175. else solve();
  176. return ;
  177. }

Codeforces GYM 100114 D. Selection 线段树维护DP的更多相关文章

  1. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  2. Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)

    题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...

  3. Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp

    D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...

  4. Codeforces 834D The Bakery 【线段树优化DP】*

    Codeforces 834D The Bakery LINK 题目大意是给你一个长度为n的序列分成k段,每一段的贡献是这一段中不同的数的个数,求最大贡献 是第一次做线段树维护DP值的题 感觉还可以, ...

  5. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

  6. Codeforces 1383E - Strange Operation(线段树优化 DP or 单调栈+DP)

    Codeforces 题目传送门 & 洛谷题目传送门 Yet another 自己搞出来的难度 \(\ge 2800\) 的题 介绍一个奇奇怪怪的 \(n\log n\) 的做法.首先特判掉字 ...

  7. 【BZOJ2164】采矿 树链剖分+线段树维护DP

    [BZOJ2164]采矿 Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n ...

  8. 【8.26校内测试】【重构树求直径】【BFS模拟】【线段树维护DP】

    题目性质比较显然,相同颜色联通块可以合并成一个点,重新建树后,发现相邻两个点的颜色一定是不一样的. 然后发现,对于一条链来说,每次把一个点反色,实际上使点数少了2个.如下图 而如果一条链上面有分支,也 ...

  9. 2019牛客暑期多校训练营(第二场)E 线段树维护dp转移矩阵

    题意 给一个\(n\times m\)的01矩阵,1代表有墙,否则没有,每一步可以从\(b[i][j]\)走到\(b[i+1][j]\),\(b[i][j-1]\),\(b[i][j+1]\),有两种 ...

随机推荐

  1. 【转】APUE学习1:迈出第一步,编译myls.c

    原文网址:http://blog.csdn.net/sddzycnqjn/article/details/7252444 注:以下写作风格均学习自潘云登前辈 /******************** ...

  2. VS2010使用EventHandler发邮件

    转:http://blog.csdn.net/alfred_72/article/details/9980279 因为不知道VS2010 Sharepoint 有EventReciver这个添加项,走 ...

  3. MySQL索引与优化策略

    1. MySQL索引实现 在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,下面主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式. MyISAM索引实现 M ...

  4. LXD 2.0 系列(二):安装与配置

    导读 简单来说,LXD是一个守护进程,为LXC容器的管理提供一组REST API.主要目标是提供一种类虚拟机的用户体验,是一种第三方的容器管理工具.下面呢,我们来介绍LXD 2.0 的安装与配置 安装 ...

  5. java web 学习三(Tomcat 服务器学习和使用2)

    一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下:

  6. hashCode之一--两个对象值相同,有相同的hash code

    两个对象值相同(x.equals(y) == true),则一定有相同的hash code. 这是java语言的定义:  因为:Hash,一般翻译做“散列”,也有直接音译为"哈希" ...

  7. Android中GridView滚动到底部加载数据终极版

    之前在项目中有一个需求是需要GridView控件,滚动到底部自动加载.但是呢GridView控件并不提供诸如ListView监听滚动到底部的onScrollListener方法,为了实现这样一个效果, ...

  8. A Spy in the Metro

    题意: n个车站,已知到达相邻车站的时间,有m1辆车从1站出发已知发车时间,有m2辆车从n站出发已知发车时间,求从1到达n所需等车的总时间最小. 分析: 有三种情况,在原地等,乘左到右的车,乘右到左的 ...

  9. cocos2d-x知识巩固-基础篇(1)

    有段时间没有学习cocos2dx了,作为新人,自己觉得还是要稳扎稳打,一点点的去积累,梳理好每一个知识点,这样对自己的成长能够有一个更清晰的认识,以便做更好的提高. 从2013年8月开始接触cocos ...

  10. RPC框架motan: 通信框架netty之Netty4Client

    上文已经初步探讨了如何实现一个具体的transport,本文就来讨论一个具体的transport,本文讨论netty4的的相关实现.老规矩,看看motan-transport的目录结构. 其中最重要的 ...