bzoj 3295 (洛谷3157、3193) [Cqoi2011]动态逆序对——树套树 / CDQ分治
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3295
题目--洛谷3157:https://www.luogu.org/problemnew/show/P3157
题目--洛谷3193:https://www.luogu.org/problemnew/show/P1393
1.树状数组套权值线段树
有点卡空间。线段树节点的*100怎么算?
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=1e5+;
int n,m,f[N],rt[N],tot,ps[N];
ll ans;
struct Node{
int ls,rs,sum;
}a[N*];
int getsm(int x)
{
int ret=;for(;x;x-=(x&-x))ret+=f[x];return ret;
}
void addsm(int x)
{
for(;x<=n;x+=(x&-x))f[x]++;
}
void insert(int &cr,int l,int r,int p,int fx)
{
if(!cr)cr=++tot;a[cr].sum+=fx;
if(l==r)return;
int mid=((l+r)>>);
if(p<=mid)insert(a[cr].ls,l,mid,p,fx);
else insert(a[cr].rs,mid+,r,p,fx);
}
void insert(int x,int v,int fx)
{
for(;x<=n;x+=(x&-x))insert(rt[x],,n,v,fx);
}
int query(int cr,int l,int r,int x)
{
if(r<=x)return a[cr].sum;
int mid=((l+r)>>);
if(x<=mid)return query(a[cr].ls,l,mid,x);
return a[a[cr].ls].sum+query(a[cr].rs,mid+,r,x);
}
int query(int x,int v)
{
int ret=;for(;x;x-=(x&-x))ret+=query(rt[x],,n,v);return ret;
}
int pre(int p,int x)
{
return query(p,n)-query(p,x);
}
int suf(int p,int x)
{
return query(n,x)-query(p,x);
}
int main()
{
scanf("%d%d",&n,&m);int x;
for(int i=;i<=n;i++)
{
scanf("%d",&x);ans+=getsm(n)-getsm(x);
addsm(x);insert(i,x,);ps[x]=i;
}
for(int i=;i<=m;i++)
{
printf("%lld\n",ans);scanf("%d",&x);
ans-=pre(ps[x],x)+suf(ps[x],x);
insert(ps[x],x,-);
}
return ;
}
加上离散化就能过洛谷3193了。通过数喜+1。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=4e4+;
int n,m,f[N],rt[N],tot,vl[N];
ll ans,tp[N],t[N];
struct Node{
int ls,rs,sum;
}a[N*];
int getsm(int x)
{
int ret=;for(;x;x-=(x&-x))ret+=f[x];return ret;
}
void addsm(int x)
{
for(;x<=n;x+=(x&-x))f[x]++;
}
void insert(int &cr,int l,int r,int p,int fx)
{
if(!cr)cr=++tot;a[cr].sum+=fx;
if(l==r)return;
int mid=((l+r)>>);
if(p<=mid)insert(a[cr].ls,l,mid,p,fx);
else insert(a[cr].rs,mid+,r,p,fx);
}
void insert(int x,int v,int fx)
{
for(;x<=n;x+=(x&-x))insert(rt[x],,n,v,fx);
}
int query(int cr,int l,int r,int x)
{
if(r<=x)return a[cr].sum;
int mid=((l+r)>>);
if(x<=mid)return query(a[cr].ls,l,mid,x);
return a[a[cr].ls].sum+query(a[cr].rs,mid+,r,x);
}
int query(int x,int v)
{
int ret=;for(;x;x-=(x&-x))ret+=query(rt[x],,n,v);return ret;
}
int pre(int p,int x)
{
return query(p,n)-query(p,x);
}
int suf(int p,int x)
{
return query(n,x)-query(p,x);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%lld",&t[i]),tp[i]=t[i];
sort(tp+,tp+n+);int cnt=unique(tp+,tp+n+)-tp-;
for(int i=;i<=n;i++)vl[i]=lower_bound(tp+,tp+cnt+,t[i])-tp;
for(int i=;i<=n;i++)
{
ans+=getsm(n)-getsm(vl[i]);
addsm(vl[i]);insert(i,vl[i],);
}
printf("%lld ",ans);int x;
for(int i=;i<=m;i++)
{
scanf("%d",&x);
ans-=pre(x,vl[x])+suf(x,vl[x]);
insert(x,vl[x],-);printf("%lld ",ans);
}
return ;
}
2.CDQ分治
学习TJ。https://www.cnblogs.com/candy99/p/6440745.html
1)先按位置排序,再按时间分治。
2)把影响加到树状数组里。往下递归之前先撤销修改。
3)应该是空间n+m,时间 (n+m) * log(n) * log(n)。(一个log分治,一个log树状数组,(n+m)是每一层的操作次数)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e5+,M=5e4+;
int n,m,tot,pos[N],f[N]; //树状数组是值
ll ans[M];
struct Cz{
int t,ps,v,id,type;
Cz(int t=,int p=,int v=,int i=,int y=):t(t),ps(p),v(v),id(i),type(y) {}
bool operator<(const Cz k)const
{
return ps<k.ps;
}
}a[N+M],tp[N+M];
void add(int x,int v)
{
for(;x<=n;x+=(x&-x))f[x]+=v;
}
int query(int x)
{
int ret=;for(;x;x-=(x&-x))ret+=f[x];return ret;
}
void CDQ(int l,int r) //l,r是时间,也已经是角标
{
if(l==r)return;
int mid=((l+r)>>);
for(int i=l;i<=r;i++)
if(a[i].t<=mid)add(a[i].v,a[i].type);
else ans[a[i].id]+=a[i].type*(query(n)-query(a[i].v)); //在我前面、比我大的
for(int i=l;i<=r;i++) if(a[i].t<=mid)add(a[i].v,-a[i].type); //撤销操作,不影响递归下去 for(int i=r;i>=l;i--)
if(a[i].t<=mid)add(a[i].v,a[i].type);
else ans[a[i].id]+=a[i].type*query(a[i].v-); //在我后面、比我小的
for(int i=r;i>=l;i--) if(a[i].t<=mid) add(a[i].v,-a[i].type); //撤销操作 int p0=l,p1=mid+;
for(int i=l;i<=r;i++)
if(a[i].t<=mid)tp[p0++]=a[i]; //去左边/右边,但没有改变相对位置。
else tp[p1++]=a[i]; //即一开始的按位置排序效果还在
for(int i=l;i<=r;i++)a[i]=tp[i];
CDQ(l,mid);CDQ(mid+,r);
}
int main()
{
scanf("%d%d",&n,&m);int x;
for(int i=;i<=n;i++)
{
scanf("%d",&x);pos[x]=i;
a[++tot]=Cz(tot,i,x,,);
}
for(int i=;i<=m;i++)
{
scanf("%d",&x);
a[++tot]=Cz(tot,pos[x],x,i,-);
}
sort(a+,a+tot+);
CDQ(,tot);
for(int i=;i<m;i++)printf("%lld\n",ans[i]),ans[i+]+=ans[i]; //ans求出来的其实是每个操作引起的变化量
return ; //(它不是一直在*type么)
}
bzoj 3295 (洛谷3157、3193) [Cqoi2011]动态逆序对——树套树 / CDQ分治的更多相关文章
- 【洛谷3157】[CQOI2011] 动态逆序对(CDQ分治)
点此看题面 大致题意: 给你一个从\(1\)到\(n\)的排列,问你每次删去一个元素后剩余的逆序对个数. 关于\(80\)分的树套树 为了练树套树,我找到了这道题目. 但悲剧的是,我的 线段树套\(T ...
- BZOJ 3295:[Cqoi2011]动态逆序对(三维偏序 CDQ分治+树状数组)
http://www.lydsy.com/JudgeOnline/problem.php?id=3295 题意:简单明了. 思路:终于好像有点明白CDQ分治处理三维偏序了.把删除操作看作是插入操作,那 ...
- bzoj3295 洛谷P3157、1393 动态逆序对——树套树
题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...
- [bzoj3295][Cqoi2011]动态逆序对_主席树
动态逆序对 bzoj-3295 Cqoi-2011 题目大意:题目链接. 注释:略. 想法:直接建立主席树. 由于是一个一个删除,所以我们先拿建立好的root[n]的权值线段树先把总逆序对求出来,接着 ...
- [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)
[BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...
- BZOJ 3295: [Cqoi2011]动态逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3865 Solved: 1298[Submit][Sta ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- 洛谷 P3157 [CQOI2011]动态逆序对 解题报告
P3157 [CQOI2011]动态逆序对 题目描述 对于序列\(A\),它的逆序对数定义为满足\(i<j\),且\(A_i>A_j\)的数对\((i,j)\)的个数.给\(1\)到\(n ...
- bzoj千题计划146:bzoj3295: [Cqoi2011]动态逆序对
http://www.lydsy.com/JudgeOnline/problem.php?id=3295 正着删除看做倒着添加 对答案有贡献的数对满足以下3个条件: 出现时间:i<=j 权值大小 ...
随机推荐
- iOS开发进阶 - 使用Carthage管理iOS第三方库
移动端访问不佳,请访问我的个人博客 最近在研究Swift,一不小心发现一个好的的管理iOS第三方库Carthage,就跟第一次使用CocoaPods时一样兴奋不已,在研究了大半天后终于能用了,使用起来 ...
- LeetCode——Diameter of Binary Tree
LeetCode--Diameter of Binary Tree Question Given a binary tree, you need to compute the length of th ...
- BI项目中的ETL设计详解(数据抽取、清洗与转换 )(转载)
原文:http://www.cnblogs.com/reportmis/p/5939732.html ETL是BI项目最重要的一个环节,通常情况下ETL会花掉整个项目的1/3的时间,ETL设计的好坏直 ...
- CSS3 网格布局(grid-layout)基础知识 - 网格模板属性(grid-template)使用说明
CSS3引入了新的网格布局(grid layout),以适应显示和设计技术的发展(尤其是移动设备优先的响应式设计). 主要目标是建立一个稳定可预料且语义正确的网页布局模式,用来替代过往表现不稳定且繁琐 ...
- 20165332实验三 敏捷开发与XP实践
20165332实验三 敏捷开发与XP实践 实验内容 1:XP基础 2:XP核心实践 3:相关工具 实验1 在IDEA中使用工具(Code->Reformate Code)把下面代码重新格式化, ...
- 如何学好C++语言
前段时间写了一篇如何学好C语言,就有人回复问我如何学好C++,所以,我把我个人的一些学习经验写在这里,希望对大家有用.首先,因为如何学好C语言中谈到了算法和系统,所以这里就只谈C++语言. C++是最 ...
- 移动国家号(MCC)
定义移动国家号 Mobile Country Code (MCC)由三位十进制数组成,它表明移动用户(或系统)归属的国家. 格式移动国家号(MCC)由三个十进制数组成,编码范围为十进制的000-999 ...
- 【OpenGL ES】关于VBO(Vertex Buffer Object)的一些坑——解析一些关于glBuffer的函数
最近在写毕设的时候用到OpenGL ES中的VBO,由于对一些接口用到的变量不了解被坑得很惨,在此记录一下防止以后再被坑. 本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cn ...
- mongodb停止遇到shutdownServer failed: unauthorized: this command must run from localhost when running db without auth解决方法
停止mongodb use admin db.shutdownServer(); mongos> db.shutdownServer(); assert failed : unexpected ...
- jquery实现全选、不选、反选的两种方法
在取复选框checkbox的属性checked属性值时,发现一个问题,就是当用attr取值时,真的为"checked",假的为"undefined";当用pro ...