#182. 「2019冬令营提高组」定价

先瞄下数据范围

对于所有数据,1≤n≤1000,1≤m≤10^9,1≤q≤500000 。\textbf{2 操作的个数不超过 1000。}

$10^9$位,看起来挺吓人,咋维护每个可以为1的位鸭?

再仔细看看,$q<=500000$,最多500000次操作,那么显然是对每一列,开个动态开点线段树或者平衡树维护。

本题对数据结构要求不高,于是我们可以快捷地用set代替辣

接下来我们考虑如何求出价格和的最小值

2 操作的个数不超过 1000。

这告诉我们可以愉快地在O(nlogn)内解决

从左到右一列列扫过去........考虑贪心

切一段ppt

我们先总结一下贪心的时候在干啥。

假设我们上一行有若干位为1,那么对于下一行,我们需要找到最高的为1位,满足这一行这位不能再为1了,我们就需要选取在这个位置之前的一个可以变成1的0,把它变成1,并把后面的位置全变成0。

直接用bitset维护可以获得部分分。

我们考虑使用一个栈维护当前的1,假设我们能找到最高的不能继续为1的位,我们就可以从这一位开始依次遍历前面的1,找到这个1之前第一个可以变成1的位置,如果这个位置在下一个1之前就是答案。

举个栗子

设前面$i$列处理完后,已知第$i$列的最小值$=(10101101)_{2}$

而第$i+1$列允许为$1$的位(从左到右,从$1$开始)有第$1,2,3,4,5,6$位

加入没有限制,那么第$i+1$列的最优解$=(10101110)_{2}$

但是允许为$1$的位不包括第$7$位鸭

于是我们就只能再向左找,找到第$4$位

把第$4$位改为$1$,并将右边所有位改为$0$

最后第$i+1$列的最优解$=(10110000)_{2}$

即为:

$a[i]=(10101101)_{2}$

$a[i+1]=(10110000)_{2}$

然后顺便维护下答案就ok了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set> namespace IO {
const int lim = ( << ) + ; char buf[lim + ], *S, *T; inline char gc() {
if (S == T) {
T = (S = buf) + fread(buf, , lim, stdin);
if (S == T) return EOF;
}
return *S++;
} inline int read() {
int x; char c; bool f;
for (f = ; (c = gc()) < '' || c > ''; f = c == '-');
for (x = c ^ ''; (c = gc()) >= '' && c <= ''; x = (x << ) + (x << ) + (c ^ ''));
return f ? -x : x;
}
}
using namespace IO;//快读是题目给的(逃 using namespace std;
const int mod=1e9+;
int n,m,q,stk[],v[],tp;
set <int> s[];
set <int>::iterator it;
int Pow(int x,int y){
int re=;
for(;y;y>>=,x=1ll*x*x%mod)
if(y&) re=1ll*re*x%mod;
return re;
}
int solve(){
int re=; tp=;
for(int i=,j;i<=n;++i){
stk[tp+]=m+;
for(j=;j<=tp&&s[i].count(stk[j]);++j);//这一位填不了的话就从这位开始找
tp=j-;
for(;;){
it=s[i].upper_bound(stk[tp+]-);
if(it==s[i].begin()) return -;
--it;
if(*it>stk[tp]){stk[++tp]=*it; break;}
if(!tp) return -;
--tp;
}
v[tp]=v[tp-]+Pow(,m-stk[tp]);//上个的答案(用数组维护)加上这一位
if(v[tp]>=mod) v[tp]-=mod;
re+=v[tp];
if(re>=mod) re-=mod;
}return re;
}
int main(){
freopen("price.in","r",stdin);
freopen("price.out","w",stdout);
n=read(); m=read(); q=read();
int q1,q2;
while(q--){
if(read()==){
q1=read(); q2=read();
if(s[q1].count(q2)) s[q1].erase(q2);
else s[q1].insert(q2);
}else printf("%d\n",solve());
}return ;
}

fjwc2019 D2T2 定价 (栈+set+贪心)的更多相关文章

  1. vijos 1605 双栈排序 - 贪心 - 二分图

    题目传送门 传送门I 传送门II 题目大意 双栈排序,问最小字典序操作序列. 不能发现两个数$a_{j}, a_{k}\ \ (j < k)$不能放在同一个栈的充分必要条件时存在一个$i$使得$ ...

  2. 洛谷P1155 双栈排序(贪心)

    题意 题目链接 Sol 首先不难想到一种贪心策略:能弹则弹,优先放A 然后xjb写了写发现只有\(40\),原因是存在需要决策的情况 比如 \(A = {10}\) \(B = {8}\) 现在进来一 ...

  3. 洛谷$P1155$ 双栈排序 贪心+二分图匹配

    正解:贪心+二分图匹配 解题报告: 传送门$QwQ$ 跪了,,,我本来以为我$NOIp$做得差不多了,,,然后康了一眼发现没做多少啊其实$QAQ$ 然后来康题趴$QwQ$ 首先考虑如果只有一个栈的情况 ...

  4. $[NOIp2008]$双栈排序 栈/二分图/贪心

    \(Sol\) 先考虑单栈排序,怎么样的序列可以单栈排序呢?设\(a_i\)表示位置\(i\)是哪个数.\(\exist i<j<k\),都没有\(a_k<a_i<a_j\), ...

  5. fjwc2019 D6T2 密文(trie+贪心)

    #194. 「2019冬令营提高组」密文 设$s[i]$表示前$i$个密文的异或和 容易发现,只要知道$s[0]~s[n](s[0]=0)$就可以知道每一位的值. 转化一下,就变成了在完全图上求最小生 ...

  6. fjwc2019 D3T1 签到题 (贪心)

    #184. 「2019冬令营提高组」签到题 每次询问接近O(1).......考虑贪心 怎么贪心呢? 对于相邻的两个数,我们要保证异或x后单调不降 我们找到两个数二进制上最高的相异位 当左边的数相异位 ...

  7. 51Nod 1272 最大距离 (栈或贪心)

    #include <cstdio> #include <queue> #include <cstring> #include <iostream> #i ...

  8. BZOJ 4029 [HEOI2015] 定价 ( 数位DP/贪心 )

    前言 最近学了数位DP,感觉挺简单又实用.这道题就比较水,可以用300B的贪心过掉-网上似乎大多是贪心的题解,我就写写DP的做法 题意 给出正整数区间[L,R][L,R][L,R],定义荒谬值为 (去 ...

  9. 【TOJ 4493】Remove Digits(单调栈贪心)

    描述 Given an N-digit number, you should remove K digits and make the new integer as large as possible ...

随机推荐

  1. jenkins openshift 持续集成

    参数部分没有 不要照抄,只供参考 需求: CI利用confd+etcd生成配置文件 CI把git的COMMIT 传到openshift的buildconfigs #!/bin/bash echo ec ...

  2. 学习笔记 python 面向对象学习

    封装: 封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏. 继承: 继承是指这样 ...

  3. VirtualBox如何扩展虚拟机Ubuntu的硬盘容量-转

    https://blog.csdn.net/ouyang_peng/article/details/53261599 摘录要点: 扩展 VBoxManage modifyhd YOUR_HARD_DI ...

  4. javaIO流

    File类(File类的概述和构造方法) A:File类的概述 File更应该叫做一个路径 文件路径或者文件夹路径 路径分为绝对路径和相对路径 绝对路径是一个固定的路径,从盘符开始 相对路径相对于某个 ...

  5. java 之多线程

    多线程基本概念_程序_线程 1.1程序.进程.线程 程序:Program是一个指令的集合 进程:Process(正在执行中的程序)是一个静态的概念.进程是程序的一次静态执行过程,占用特定的地址空间.每 ...

  6. InstallShield2015制作安装包----------安装过程中修改文件内容

    //修改安装目录下autostart.vbs里的路径 //打开文件 OpenFileMode(FILE_MODE_NORMAL); strPath=INSTALLDIR+"centerAut ...

  7. jQuery_ajax请求超时

    设置timeout的时间,通过检测complete时status的值判断请求是否超时,如果超时执行超时的操作. $.ajax({ url:'', timeout : 1000, //超时时间设置,单位 ...

  8. 三级菜单(低端版VS高端版)

    >>>低端版 menu={'山西': {'太原': {'迎泽':['柳巷','五一广场','太原站'], '小店':['山西财经大学','山西大学','武宿机场'], '晋源':[' ...

  9. python多线程,多进程编程。

    进程,是目前计算机中为应用程序分配资源的最小单位: 线程,是目前计算机中运行应用程序的最小单位: 在实际系统中,其实进程都是被分为线程来实现的,所以参与时间片轮转的是线程: 但是管理应用程序的资源的单 ...

  10. uva 11183 Teen Girl Squad

    题意: 有一个女孩,需要打电话让所有的人知道一个消息,消息可以被每一个知道消息的人传递. 打电话的关系是单向的,每一次电话需要一定的花费. 求出打电话最少的花费或者判断不可能让所有人知道消息. 思路: ...