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,表示到这儿,所需要的最小代价是多少

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <string>
#include <ctime>
#include <list>
#include <bitset>
typedef unsigned char byte;
#define pb push_back
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
#define local freopen("in.txt","r",stdin)
#define pi acos(-1) using namespace std;
const int maxn = 1e5 + ;
char str[maxn];
int length , sum[maxn], dp[maxn];
vector<int>Q,Q2; struct operation
{
int x;
int type;
}; operation nxt[maxn]; struct QueryData
{
int minv , minpos;
QueryData(int minv , int minpos)
{
this->minv = minv , this->minpos = minpos;
}
}; typedef int SgTreeDataType;
struct treenode
{
int L , R ;
SgTreeDataType minv , minpos;
void updata(SgTreeDataType v)
{
minv = v;
}
}; treenode tree[maxn * ]; inline void push_up(int o)
{
if(tree[o*].minv > tree[o*+].minv)
{
tree[o].minv = tree[o*+].minv;
tree[o].minpos = tree[o*+].minpos;
}
else
{
tree[o].minv = tree[o*].minv;
tree[o].minpos = tree[o*].minpos;
}
} inline void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R,tree[o].minv = << , tree[o].minpos = ;
if(L == R) tree[o].minpos = L;
if (R > L)
{
int mid = (L+R) >> ;
build_tree(L,mid,o*);
build_tree(mid+,R,o*+);
}
} inline void updata(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) tree[o].updata(v);
else
{
int mid = (L+R)>>;
if (QL <= mid) updata(QL,QR,v,o*);
if (QR > mid) updata(QL,QR,v,o*+);
push_up(o);
}
} inline QueryData query(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return QueryData(tree[o].minv,tree[o].minpos);
else
{
int mid = (L+R)>>;
if (QL <= mid && QR > mid)
{
QueryData a = query(QL,QR,*o);
QueryData b = query(QL,QR,*o+);
if(a.minv < b.minv) return a;
else return b;
}
else if (QL <= mid) return query(QL,QR,*o);
else return query(QL,QR,*o+);
}
} void initiation()
{
memset( dp , , sizeof(dp));
scanf("%d%s",&length,str+);sum[] = ;
for(int i = ; i <= length ; ++ i)
{
sum[i] = sum[i-];
if(str[i] == '*')
{
Q.push_back(i);
}
else
{
sum[i] ++ ;
Q2.push_back(i);
}
}
} void solve()
{
int sz = Q.size();
int ansL = Q[],ansR = Q[],ans=sz;
build_tree( , sz - , );
for(int i = ; i < sz ; ++ i) updata( i , i , sum[Q[i]] - i , );
for(int i = ; i < sz - ; ++ i)
{
QueryData y = query( i + , sz - , );
int newans = i + + sz + y.minv - sum[Q[i]];
if(newans < ans)
{
ans = newans;
ansL = i;
ansR = y.minpos;
}
}
printf("%d\n",ans);
if(ansL != ansR)
{
printf("%d\n",Q[ansL]);
printf("Shift+%d\n",Q[ansR]);
for(int i = ; i < sz ; ++ i) if(i < ansL || i > ansR) printf("Ctrl+%d\n",Q[i]);
for(int i = ; i < Q2.size() ; ++ i) if( Q2[i] < Q[ansR] && Q2[i] > Q[ansL]) printf("Ctrl+%d\n",Q2[i]);
}
else
{
printf("%d\n",Q[]);
for(int i = ; i < sz ; ++ i) printf("Ctrl+%d\n",Q[i]);
}
} int main(int argc,char *argv[])
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
initiation();
if(Q.size() == ) printf("0\n");
else if(Q.size() == ) printf("1\n%d\n",Q[]);
else if(Q.size() == ) printf("2\n%d\nCtrl+%d\n",Q[],Q[]);
else solve();
return ;
}

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. Hibernate向MySQL插入中文数据--乱码解决

    <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/exam?useUnicod ...

  2. 【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”

    原文网址:http://www.cnblogs.com/Dageking/archive/2013/05/15/3079394.html VS2012编译出来的程序,在XP上运行,出现“.exe 不是 ...

  3. TCP/IP详解学习笔记(11)-TCP交互数据流,成块数据流

    目前建立在TCP协议上的网络协议特别多,有telnet,ssh,有ftp,有http等等.这些协议又可以根据数据吞吐量来大致分成两大类:(1)交互数据类型,例如telnet,ssh,这种类型的协议在大 ...

  4. jQuery-对Radio/CheckBox的操作集合

    jQuery获取Radio选择的Value值 $("input[name='radio_name'][checked]").val(); //选择被选中Radio的Value值 $ ...

  5. 怎样查看Eclipse是32位还是64位

    首先进入到Eclipse的安装目录,如下图:   查找到文件名为"eclipse.ini" 文件,使用文本编辑工具,或记事本打开,如下图: 如图中的红框所示,如果是win32.x8 ...

  6. 【转】简单内存泄漏检测方法 解决 Detected memory leaks! 问题

    我的环境是: XP SP2 . VS2003 最近在一个项目中,程序退出后都出现内存泄漏: Detected memory leaks! Dumping objects -> {98500} n ...

  7. Android桌面快捷方式那些事与那些坑

    原文来自http://blog.zanlabs.com/2015/03/14/android-shortcut-summary/ 将近二个多月没写博客了.之前一段时间一直在搞红包助手,就没抽时间写博客 ...

  8. C# 中LinkLabel的简单使用

    界面中加入一个LinkLabel控件

  9. c# 进行AE开发时,如何在地图上定位出一个点

    一.文本形式的气泡提示框 由于本人是初学,所以具体的含义尚未弄清楚,直接给出代码吧!

  10. 《Python CookBook2》 第四章 Python技巧 对象拷贝 && 通过列表推导构建列表

    (先学第四章) 对象拷贝 任务: Python通常只是使用指向原对象的引用,并不是真正的拷贝. 解决方案: >>> a = [1,2,3] >>> import c ...