[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. 停止ambari上服务的顺序

    Before performing any upgrades or uninstalling software, stop all of the Hadoop services in the foll ...

  2. 开发中常遇到的Python陷阱和注意点

    最近使用Python的过程中遇到了一些坑,例如用datetime.datetime.now()这个可变对象作为函数的默认参数,模块循环依赖等等. 在此记录一下,方便以后查询和补充. 避免可变对象作为默 ...

  3. css做中划线与文字排版

    html: <div class="spilt">    <span class="left"></span>    < ...

  4. Java中一些知识的归纳总结

    1.包装类型与基本数据类型的区别. Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这使得Java在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据 ...

  5. 按小时或天切割Nginx日志

    #按小时或天切割Nginx日志到备份文件夹 LOGS_PATH=/home/www/logs/thc SAVE_PATH=/home/www/logs/thc YESTERDAY=$(date -d ...

  6. Ubuntu下修改NAT模式的IP地址

    1,查看虚拟机的网段 在编辑->虚拟网络编辑器->NAT设置->网关 IP  可以查看到虚拟机的网关 如图 2,图形化设置: 图中 Netmask设置的是255.255.255.0 ...

  7. bzoj1577 [Usaco2009 Feb]庙会捷运Fair Shuttle

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1577 [题解] 我们把每坨奶牛按s排个序. 对于每坨奶牛,如果车上有空位置就塞. 否则,看下 ...

  8. UpdateData的用法(转)

    原文转自 https://blog.csdn.net/ddjj_1980/article/details/51452289 UpdateData(TRUE)——刷新控件的值到对应的变量.(外部输入值交 ...

  9. Linux下的Backlight子系统(一)【转】

    转自:http://blog.csdn.net/weiqing1981127/article/details/8511676 版权所有,转载必须说明转自 http://my.csdn.net/weiq ...

  10. java 生成execl下载

    /** * execl Export */ private void createExecl(HttpServletRequest request, HttpServletResponse respo ...