LGP5386题解
写在前面的废话
自己写了两天,调了半天,然后jzp来帮忙调了一个小时,终于过了
过的时候耳机里放着桐姥爷的bgm,就差哭出来了
题解
首先这题没有部分分差评(
- 值域不变
我们可以注意到,如果一个区间全部都在值域内(长度为 \(len\)),那么这个区间的答案是 \(\frac {len \times (len+1)} 2\)。
然后我们很快能发现一个区间的答案就是这样的区间的答案之和。
然后我们就能用线段树做到 \(O(\log n)\)
- 区间不变
此时我们在值域上进行莫队。
记录每个值对应的区间下标,然后可以视为这样的一个问题:
- 加边
- 询问所有联通块的贡献之和
我们当然能够使用可撤销并查集做到 \(O(m\sqrt n\log n)\)。
但仔细想想,把莫队改为回滚莫队可以使用普通并查集做到 \(O(m\sqrt n\alpha(n))\)。
- 原问题
对序列分块,在莫队时维护块内答案和并查集即可。
整块和散块之间的答案使用算法 \(1\) 的方法即可求解。
复杂度 \(O(m\sqrt n\alpha(n))\),但是因为我并查集挂掉了所以只加了一个优化(
不过这题数据好像没卡,\(O(m\sqrt n\log n)\) 过去了。
附上 AC 前的最后一版代码:
#include<algorithm>
#include<cstdio>
const int M=2e5+5,p=448,SIZ=p+5;
int n,m,len,a[M];long long ans[M];
int L[SIZ],R[SIZ],id[M],pos[M];
int top,valp[M],vald[M],vals[M];
bool vs[SIZ],vis[SIZ][SIZ];int t,pv[M],as[M];
struct Query{
int L,R,x,y,p,id;
inline bool operator<(const Query&it)const{
return p==it.p?y<it.y:x<it.x;
}
}q[M];
struct data{
int L,R,len;long long ans;
inline data operator*(const data&it)const{
return (data){L+(L==len)*it.L,(it.R==it.len)*R+it.R,len+it.len,ans+it.ans+R*it.L};
}
inline void AddL(const bool&val){
if(val){
ans+=++L;if(R==len)++R;
}
else L=0;++len;
}
inline void AddR(const bool&val){
if(val){
ans+=++R;if(L==len)++L;
}
else R=0;++len;
}
};
struct Block{
int ans,len,f[SIZ],siz[SIZ];bool v[SIZ];
inline void init(){
for(register int i=0;i<=len;++i)siz[f[i]=i]=1,v[i]=false;ans=0;
}
inline void merge(const int&u,const int&v){
if(siz[u]>siz[v])siz[f[v]=u]+=siz[v];
else siz[f[u]=v]+=siz[u];
}
inline int Find(const int&u){
return f[u]==u?u:f[u]=Find(f[u]);
}
inline void Add(const int&id){
ans+=siz[Find(id-1)]*siz[Find(id)];merge(Find(id-1),Find(id));v[id]=true;
}
inline data Q(){
return (data){siz[Find(0)]-1,siz[Find(len)]-1,len,ans};
}
}B[SIZ];
inline void Update(const int&bid,const int&pos){
if(vis[pos][bid])return;vis[pos][bid]=true;
if(!vs[pos])++t,vs[pos]=true,as[t]=B[pv[t]=pos].ans;
++top;vals[top]=B[valp[top]=pos].siz[vald[top]=bid];
}
inline void Modify(const int&l,const int&r){
register int i,p;
for(i=l;i<=r;++i){
p=pos[a[i]];Update(B[p].Find(id[a[i]]),p);Update(B[p].Find(id[a[i]]-1),p);
}
for(i=l;i<=r;++i)B[pos[a[i]]].Add(id[a[i]]);
}
inline void clear(const int&L,const int&R){
for(register int i=L;i<=R;++i)B[pos[a[i]]].v[id[a[i]]]=false;
}
inline void Add(const int&val){
B[pos[val]].Add(id[val]);
}
inline long long Q(const int&l,const int&r){
const int&q=pos[l],&p=pos[r];
register int i;data ans=(data){0,0,0,0};
if(q==p){
for(i=l;i<=r;++i)ans.AddR(B[q].v[id[i]]);
}
else{
for(i=q+1;i<p;++i)ans=ans*B[i].Q();
for(i=R[q];i>=l;--i)ans.AddL(B[q].v[id[i]]);
for(i=L[p];i<=r;++i)ans.AddR(B[p].v[id[i]]);
}
return ans.ans;
}
inline void init(){
register int i,x;
scanf("%d%d",&n,&m);len=(n+p-1)/p;
for(i=1;i<=n;++i){
scanf("%d",&x);a[x]=i;
pos[i]=(i-1)/p+1;id[i]=(i-1)%p+1;
}
for(i=1;i<=len;++i){
L[i]=R[i-1]+1;R[i]=p*i;
if(i==len)R[i]=n;B[i].len=R[i]-L[i]+1;
}
for(i=1;i<=m;++i){
scanf("%d%d%d%d",&q[i].L,&q[i].R,&q[i].x,&q[i].y);
q[i].p=pos[q[i].x];q[i].id=i;
}
}
inline void Mo_queue(){
register int i,j,b,d,id;
std::sort(q+1,q+m+1);
for(i=1;i<=m;++i){
const int&QL=q[i].x,&QR=q[i].y;
if(i==1||q[i].p!=q[i-1].p){
for(j=1;j<=len;++j)B[j].init();id=q[i].p*p;
}
if(pos[QL]==pos[QR])Modify(QL,QR);
else{
while(id<QR)Add(a[++id]);
Modify(QL,q[i].p*p);
}
ans[q[i].id]=Q(q[i].L,q[i].R);
do{
b=valp[top];d=vald[top];
B[b].f[d]=d;B[b].siz[d]=vals[top];vis[b][d]=false;
}while(--top);
do B[pv[t]].ans=as[t],vs[pv[t]]=false;while(--t);
if(pos[QL]==pos[QR])clear(QL,QR);else clear(QL,q[i].p*p);
}
}
signed main(){
init();Mo_queue();
for(register int i=1;i<=m;++i)printf("%lld\n",ans[i]);
}
LGP5386题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- 超详细的node/v8/js垃圾回收机制
前言 垃圾回收器是一把十足的双刃剑.其好处是可以大幅简化程序的内存管理代码,因为内存管理无需程序员来操作,由此也减少了(但没有根除)长时间运转的程序的内存泄漏.对于某些程序员来说,它甚至能够提升代码的 ...
- K8s多节点部署+负载均衡+keepalived ——囊萤映雪
K8s多节点部署+负载均衡+keepalived --囊萤映雪 1.多节点master2 部署 2.负载均衡部署+keepalived 1.多节点master2部署: #从master01节点上拷贝证 ...
- kubeadm/flannel/dashboard/harbor部署以及服务发布
kubeadm/flannel/dashboard/harbor部署以及服务发布 目录 kubeadm/flannel/dashboard/harbor部署以及服务发布 一.部署kubeadm 1. ...
- Ubuntu下pip3的安装、升级、卸载
1.安装 sudo apt-get install python3-pip 2.升级 sudo pip3 install --upgrade pip 3.卸载 sudo apt-get remove ...
- python数据类型内置方法
内容概要 列表内置方法 字典内置方法 字符串转换成字典的方法 eval() 元组内置方法 元组相关笔试题 集合内置方法 列表内置方法 l1 = [2, 4, 5, 7, 3, 9, 0, 6] # 升 ...
- 通过PEB寻找函数地址
通过PEB的Ldr参数(结构体定义为_PEB_LDR_DATA),遍历当前进程加载的模块信息链表,找到目标模块. 摘自PEB LDR DATA: typedef struct _PEB_LDR ...
- 使用讯飞tts+ffmpeg自动生成视频
参考 FFmpeg 讯飞离线语音合成 起因 某日,看到一个营销号的视频说做视频日进斗金,大意是用软件识别文章小说,搭配一些图片转换成自己的视频.看完当时脑海里冒出一个念头,我也可以,于是有了这番尝试. ...
- IP网络性能测试工具——Renix Perf
一.Renix Perf 基于软件的网络及应用服务性能测试工具 · 双臂测试 · 单臂测试 通过测试端点产生网络流量对网络性能进行测量 · TCP.UDP.PING · 语音.视频.HTTP.FTP. ...
- Excel数据可视化图表设计需要注意的几个问题
大数据发展迅速的时代,数据分析驱动商业决策.对于庞大.无序.复杂的数据要是没经过合适的处理,价值就无法体现. 可以想象一本没有图片的教科书.没有图表.图形或是带有箭头和标签的插图或流程图,那么这门学 ...
- 【C#TAP 异步编程】异步接口 OOP
在我们深入研究"异步OOP"之前,让我们解决一个相当常见的问题:如何处理异步方法的继承?那么"异步接口"呢? 幸运的是,它确实可以很好地与继承(和接口)一起使用 ...