[CF930E]/[CF944G]Coins Exhibition

题目地址:

CF930E/CF944G

博客地址:

[CF930E]/[CF944G]Coins Exhibition - skylee

题目大意:

一个长度为\(k(k\le10^9)\)的\(01\)串,给出\(n+m(n,m\le10^5)\)个约束条件,其中\(n\)条描述区间\([l_i,r_i]\)至少有一个\(0\),其中\(m\)条描述区间\([l_i,r_i]\)至少有一个\(1\)。求合法的\(01\)串数量。

思路:

显然直接考虑所有的\(k\)位,就算\(\mathcal O(k)\)的线性算法也会超时,因此对于所有的\(l_i-1,r_i\)以及\(0,k\)离散化以后考虑这些关键点即可。

设关键点有\(lim\)个,对所有关键点排序,\(tmp[i]\)为\(i\)离散化前对应的数。对所有关键点排序,考虑动态规划,设\(f[i][j\in\{0,1,2\}]\)表示从后往前考虑第\(i\sim lim\)个关键点。若\(j\in\{0,1\}\),则\(f[i][j]\)表示\(tmp[i]\sim tmp[i+1]\)中含有\(j\)的方案数后缀和。若\(j=2\),则\(f[i][j]\)表示最后一段同时有\(0\)和\(1\)的方案数。用\(min[j\in\{0,1\}][i]\)表示对应约束条件类型为\(j\),\(i\)右侧最近的、对应左端点不在\(i\)左侧的右端点。状态转移方程如下:

  • \(f[i][0]=f[i+1][0]+f[i+1][1]-f[min[1][i]][1]+f[i+1][2]\times(2^{tmp[i+1]-tmp[i]}-2)\)
  • \(f[i][1]=f[i+1][1]+f[i+1][0]-f[min[0][i]][0]+f[i+1][2]\times(2^{tmp[i+1]-tmp[i]}-2)\)
  • \(f[i][2]=f[i+1][0]-f[min[0][i]][0]+f[i+1][1]-f[min[1][i]][1]+f[i+1][2]\times(2^{tmp[i+1]-tmp[i]}-2)\)

最终答案为\(f[0][2]\)。

时间复杂度\(\mathcal O((n+m)(\log(n+m)+\log k))\)。其中\(\mathcal O(\log(n+m))\)为离散化复杂度,\(\mathcal O(\log k)\)为快速幂复杂度。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
using int64=long long;
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
constexpr int N=1e5,mod=1e9+7;
std::pair<int,int> p[2][N];
int tmp[N*4+2],min[2][N*4+2],f[N*4+2][3];
inline int power(int a,int k) {
int ret=1;
for(;k;k>>=1) {
if(k&1) ret=(int64)ret*a%mod;
a=(int64)a*a%mod;
}
return ret;
}
int main() {
const int k=getint(),n=getint(),m=getint();
int lim=0;
for(register int i=0;i<n;i++) {
tmp[++lim]=p[0][i].first=getint()-1;
tmp[++lim]=p[0][i].second=getint();
}
for(register int i=0;i<m;i++) {
tmp[++lim]=p[1][i].first=getint()-1;
tmp[++lim]=p[1][i].second=getint();
}
tmp[++lim]=k;
std::sort(&tmp[0],&tmp[lim]+1);
lim=std::unique(&tmp[0],&tmp[lim]+1)-&tmp[1];
for(register int i=0;i<=lim;i++) {
min[0][i]=min[1][i]=lim+1;
}
for(register int i=0;i<n;i++) {
p[0][i].first=std::lower_bound(&tmp[0],&tmp[lim]+1,p[0][i].first)-tmp;
p[0][i].second=std::lower_bound(&tmp[0],&tmp[lim]+1,p[0][i].second)-tmp;
min[0][p[0][i].first]=std::min(min[0][p[0][i].first],p[0][i].second);
}
for(register int i=0;i<m;i++) {
p[1][i].first=std::lower_bound(&tmp[0],&tmp[lim]+1,p[1][i].first)-tmp;
p[1][i].second=std::lower_bound(&tmp[0],&tmp[lim]+1,p[1][i].second)-tmp;
min[1][p[1][i].first]=std::min(min[1][p[1][i].first],p[1][i].second);
}
for(register int i=lim;i;i--) {
min[0][i-1]=std::min(min[0][i-1],min[0][i]);
min[1][i-1]=std::min(min[1][i-1],min[1][i]);
}
f[lim][0]=f[lim][1]=f[lim][2]=1;
for(register int i=lim-1;i>=0;i--) {
int g[3];
g[0]=(f[i+1][0]-f[min[0][i]][0]+mod)%mod;
g[1]=(f[i+1][1]-f[min[1][i]][1]+mod)%mod;
g[2]=(int64)f[i+1][2]*((power(2,tmp[i+1]-tmp[i])-2+mod)%mod)%mod;
f[i][0]=((int64)f[i+1][0]+g[1]+g[2])%mod;
f[i][1]=((int64)f[i+1][1]+g[0]+g[2])%mod;
f[i][2]=((int64)g[0]+g[1]+g[2])%mod;
}
printf("%d\n",f[0][2]);
return 0;
}

[CF930E]/[CF944G]Coins Exhibition的更多相关文章

  1. 【CF944G】Coins Exhibition DP+队列

    [CF944G]Coins Exhibition 题意:Jack去年参加了一个珍稀硬币的展览会.Jack记得一共有 $k$ 枚硬币,这些硬币排成一行,从左到右标号为 $1$ 到 $k$ ,每枚硬币是正 ...

  2. CF930E Coins Exhibition

    题意:平面上一共有k个硬币(k<=1e9),给你n个区间这些区间中至少有一个硬币反面朝上,m个区间中至少有一个硬币正面朝上.问有多少种硬币放置方案?n,m<=100005. 标程: #in ...

  3. [LeetCode] Arranging Coins 排列硬币

    You have a total of n coins that you want to form in a staircase shape, where every k-th row must ha ...

  4. ACM: Gym 101047M Removing coins in Kem Kadrãn - 暴力

     Gym 101047M Removing coins in Kem Kadrãn Time Limit:2000MS     Memory Limit:65536KB     64bit IO Fo ...

  5. Codeforces 2016 ACM Amman Collegiate Programming Contest A. Coins(动态规划/01背包变形)

    传送门 Description Hasan and Bahosain want to buy a new video game, they want to share the expenses. Ha ...

  6. csuoj 1119: Collecting Coins

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1119 1119: Collecting Coins Time Limit: 3 Sec  Memo ...

  7. Coins

    Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One day Hi ...

  8. hdu 1398 Square Coins (母函数)

    Square Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  9. (混合背包 多重背包+完全背包)The Fewest Coins (poj 3260)

    http://poj.org/problem?id=3260   Description Farmer John has gone to town to buy some farm supplies. ...

随机推荐

  1. Google File System中文版

    英文原文地址: Google File system 译文原文地址: The Google File System中文版 Google File System中文版 摘要 我们设计并实现了Google ...

  2. iOS 后台运行执行代码(例如定位)

  3. Spring任务调度<task:scheduled-tasks>【含cron参数详解】 (转载)

    Spring内部有一个task是Spring自带的一个设定时间自动任务调度 task使用的时候很方便,但是他能做的东西不如quartz那么的多! 可以使用注解和配置两种方式,配置的方式如下 引入Spr ...

  4. jvm面试必会基本知识

    内存: 堆区 1.new的对象实例  ps:(java堆可以细分为新生代和老年代)(通过-xmx和-xms来实现可扩展) 虚拟机栈 局部变量 本地方法栈 为虚拟机使用的native方法服务 方法区 s ...

  5. 如何让 linux unzip 命令 不输出结果

    unzip xx.zip > /dev/null 2>&1 unzip xx.zip > /dev/null前半部分是将标准输出重定向到空设备, 后面的2>&1 ...

  6. 【bzoj3196-二逼平衡树】线段树套平衡树

    http://acm.hust.edu.cn/vjudge/problem/42297 [题目描述] 写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间 ...

  7. 【STSRM13】花六游鸟小

    [题意]给定n个节点的树,每个节点有一个m位二进制数,数字可以随时按位取反,每个数位有一个价值,定义每个点的最大价值是从根到这个点路上的数字(可以取反)或起来的数字中,1有价值0无价值,加起来得到的最 ...

  8. 【洛谷 P2464】[SDOI2008]郁闷的小J(线段树)

    题目链接 这题我很久之前用分块写过,没写出来.. 今天又看到了,于是下决心把这题做出来. 这次我用线段树写的,直接对每本书的编号Hash一下然后离散化然后各建一棵线段树,维护当前编号在某个位置有没有书 ...

  9. opencv_人脸检测、模型训练、人脸识别

    人脸检测.模型训练.人脸识别 2018-08-15 今天给大家带来一套人脸识别一个小案例,主要是帮助小伙伴们解决如何入门OpenCV人脸识别的问题,现在的AI行业比较火热,AI技术的使用比较广泛.就拿 ...

  10. 如何优雅地使用minicom

    minicom简介 安装 minicom是linux下一款常用的串口调试工具.ubuntu环境下,使用如下命令安装 sudo apt-get install minicom 配置 使用前需要进行配置, ...