CF 878E Numbers on the blackboard 并查集 离线 贪心
LINK:Numbers on the blackboard
看完题觉得很难。
想了一会发现有点水 又想了一下发现有点困难。
最终想到了 但是实现的时候 也很难.
先观察题目中的这个形式 使得前后两个数字变成x+2y.
那么一个数字的变成两倍的次数固定 除了左端点至少可以变化一次.
有些数字 可以变换多次 这取决于什么 容易考虑到右端点 先变化一次 如果>0显然 可以和其左边进行合并一下.
然后 可以变换更多次 然后从右到左考虑这个过程就发现是正确的了.
这样 我们得到了一个nm的做法.
容易发现这个东西不具有区间可加性 所以不能采用线段树来维护这个东西.
不过这个过程是从左到右做的 考虑离线处理这个问题.
对于每个右端点处理左端点 显然中间的合并过程可以单调栈做一下.
考虑计算答案 单调栈存一个前缀和 然后在左端点所在区间内 再求一下值即可.
这个值可以利用线段树来做 当然也可以不需要 倒着预处理的后缀和就可以了.
一个难点是 比大小的时候可能会爆long long 这里可以预估一个INF 来防止爆掉.
也算是常见套路吧. 代码写的比较丑 因为 状态相当的不好.
const ll MAXN=100010;
ll n,m,cnt,top;
ll a[MAXN],ans[MAXN],f[MAXN],l[MAXN],r[MAXN],s[MAXN],id[MAXN];
ll qz[MAXN],hz[MAXN],mi[MAXN],INV[MAXN],w[MAXN],fac[MAXN],c[MAXN];
struct wy
{
ll id;
ll l,r;
}t[MAXN];
inline ll inv(ll x)
{
return x==1?x:inv(mod%x)*(mod-mod/x)%mod;
}
inline ll cmp(wy a,wy b){return a.r<b.r;}
inline int getfather(int x){return x==f[x]?x:f[x]=getfather(f[x]);}
inline ll ksm(ll b,ll p)
{
ll cnt=1;
while(p)
{
if(p&1)cnt=cnt*b%mod;
b=b*b%mod;p=p>>1;
}
return cnt;
}
int main()
{
//freopen("1.in","r",stdin);
get(n);get(m);mi[0]=1;fac[0]=1;
rep(1,n,i)get(a[i]),l[i]=r[i]=f[i]=i,fac[i]=fac[i-1]*2%mod,mi[i]=min(mi[i-1]*2,INF);
INV[n]=inv(fac[n]);hz[n]=a[n]*2%mod;
fep(n-1,0,i)INV[i]=INV[i+1]*2%mod,hz[i]=(hz[i+1]+a[i])*2%mod;
rep(1,m,i)
{
ll l,r;
get(l);get(r);
ans[i]=a[l];
if(l==r)continue;
t[++cnt]=(wy){i,l+1,r};
}
sort(t+1,t+1+cnt,cmp);
ll flag=1;s[++top]=1;qz[top]=w[top]=a[1];id[1]=1;
rep(2,n,i)
{
//当前端点向右移动.
ll fa=i;ll ww=a[i]*2,ss=a[i]*2;
while(top!=1&&ww>0)
{
if(ww!=INF)//更新当前块的比较值.
{
if(mi[(r[s[top]]-l[s[top]]+1)]==INF)ww=INF;
else
{
if(ww>=(INF-1)/mi[(r[s[top]]-l[s[top]]+1)]+1)ww=INF;
else ww=ww*mi[(r[s[top]]-l[s[top]]+1)];
}
}
ss=ss*fac[(r[s[top]]-l[s[top]]+1)]%mod;
if(ww!=INF)ww=min(INF,ww+w[top]);
f[fa]=s[top];ss=(ss+qz[top]-qz[top-1]+mod)%mod;
r[s[top]]=r[fa];fa=s[top];--top;
}
s[++top]=fa;qz[top]=(qz[top-1]+ss)%mod;w[top]=ww;id[fa]=top;
while(flag<=cnt&&t[flag].r==i)
{
ll xx=getfather(t[flag].l);
ans[t[flag].id]=(ans[t[flag].id]+qz[top]-qz[id[xx]]+mod)%mod;
ww=hz[t[flag].l]-hz[r[xx]+1]*fac[r[xx]+1-t[flag].l];
ans[t[flag].id]=(ans[t[flag].id]+ww)%mod;
++flag;
}
}
rep(1,m,i)putl((ans[i]+mod)%mod);
return 0;
}
CF 878E Numbers on the blackboard 并查集 离线 贪心的更多相关文章
- 【CF878E】Numbers on the blackboard 并查集
[CF878E]Numbers on the blackboard 题意:给你一个长度为n个数列,你每次可以进行如下操作: 选取两个相邻的数x,y(x在y左面),然后将这两个数去掉,用x+2y替换它. ...
- ACM: hdu 1811 Rank of Tetris - 拓扑排序-并查集-离线
hdu 1811 Rank of Tetris Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & % ...
- BZOJ5188: [Usaco2018 Jan]MooTube 并查集+离线处理
BZOJ又不给题面... Luogu的翻译看不下去... 题意简述 有一个$n$个节点的树,边有权值,定义两个节点之间的距离为两点之间的路径上的最小边权 给你$Q$个询问,问你与点$v$的距离超过$k ...
- poj 2528 Mayor's posters 线段树 || 并查集 离线处理
题目链接 题意 用不同颜色的线段覆盖数轴,问最终数轴上有多少种颜色? 注:只有最上面的线段能够被看到:即,如果有一条线段被其他的线段给完全覆盖住,则这个颜色是看不到的. 法一:线段树 按题意按顺序模拟 ...
- ACM学习历程—SNNUOJ 1110 传输网络((并查集 && 离线) || (线段树 && 时间戳))(2015陕西省大学生程序设计竞赛D题)
Description Byteland国家的网络单向传输系统可以被看成是以首都 Bytetown为中心的有向树,一开始只有Bytetown建有基站,所有其他城市的信号都是从Bytetown传输过来的 ...
- CF 500 B. New Year Permutation 并查集
User ainta has a permutation p1, p2, ..., pn. As the New Year is coming, he wants to make his permut ...
- CF # 296 C Glass Carving (并查集 或者 multiset)
C. Glass Carving time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- CF 452E. Three strings(后缀数组+并查集)
传送门 解题思路 感觉这种题都是套路之类的??首先把三个串并成一个,中间插入一些奇怪的字符,然后跑遍\(SA\).考虑按照\(height\)分组计算,就是每个\(height\)只在最高位计算一次, ...
- CF722C. Destroying Array[并查集 离线]
链接:Destroying Array C. Destroying Array time limit per test 1 second memory limit per test 256 megab ...
随机推荐
- SpringBoot2.x入门教程:理解配置文件
前提 这篇文章是<SpringBoot2.x入门>专辑的第4篇文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8. 主要介绍SpringBoot配置文件一 ...
- CF1215D Ticket Game(思维,博弈)
题目 传送门:https://www.luogu.com.cn/problem/CF1215D Idea 一列数,保证能分成左右两部分,其中有若干个数字被抹掉,两个人轮流填数,如果在把这些空缺的数字填 ...
- 05-Python模块
一.简介 模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py.模块可以被其他程序导入来使用模块具有的功能.这也是使用python标准库的方式. import time start_time ...
- 从连接器组件看Tomcat的线程模型——连接器简介
Connector组件介绍 Connector(连接器)组件是Tomcat最核心的两个组件之一,主要的职责是负责接收客户端连接和客户端请求的处理加工.每个Connector都将指定一个端口进行监听,分 ...
- 如何将你写的脚本程序打包成一个exe可执行程序
编写的程序打包成一个exe文件,随时可以双击执行,想想是不是很酷.接下来我们一起看一下如何将自己编写的程序打包为一个exe的可执行程序. 将程序打包成exe的好处 除了满足自己的成就感以外, ...
- (4)webpack中配置css,scss,less第三方loader
为什么要使用第三方loader 一般引入样式文件,我们会在html中引入样式标签. 很明显,这样就跟之前在script中引入js文件一样,会导致二次请求.我们希望webpack像处理js文件一样处理样 ...
- 用Eclipse进行单元测试JUnit4
(1)在项目中引入Jar包 (2)编写需要测试的类 public class Calculator { private static int result=0; // 静态变量,用于存储运行结 ...
- Ethical Hacking - GAINING ACCESS(18)
CLIENT SIDE ATTACKS Backdooring ANY file Combine backdoor with any file - Generic solution. Users ar ...
- 【Docker】Redis 安装使用教程
1.安装 1.1 拉取镜像 docker pull redis redis:4.0 1.2 创建redis容器名"redistest1",并开启持久化 docker run -d ...
- 利用tox打造自动自动化测试框架
什么是tox tox官方文档的第一句话 standardize testing in Python,意思就是说标准化python中的测试,那是不是很适合测试人员来使用呢,我们来看看他究竟是什么? 根据 ...