题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295

洛谷 P3157(同一道题) https://www.luogu.org/problemnew/show/P3157

洛谷 P1393(略有不同) https://www.luogu.org/problemnew/show/P1393

动态逆序对问题;

树状数组套权值线段树,动态开点;

就像树状数组那样做就可以了,每个线段树维护一段区间内的不同权值的数的个数;

删除一个点,就把答案减去它贡献的逆序对数量就可以了;

有点不太懂空间范围怎么算...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int const maxn=1e5+,maxm=maxn*;
int n,m,pos[maxn],t[maxn],rt[maxn],ls[maxm],rs[maxm],sum[maxm],cnt;
ll ans;
ll getsum(int x)
{
ll ret=;
for(;x;x-=(x&-x)) ret+=t[x];
return ret;
}
void add(int x)
{
for(;x<=n;x+=(x&-x)) t[x]++;
}
void update(int &x,int l,int r,int p,int v)
{
if(!x)x=++cnt; sum[x]+=v;
if(l==r)return;
int mid=(l+r)>>;
if(p<=mid)update(ls[x],l,mid,p,v);
else update(rs[x],mid+,r,p,v);
}
void insert(int x,int p,int v)
{
for(;x<=n;x+=(x&-x)) update(rt[x],,n,p,v);
}
ll ask(int x,int l,int r,int p)
{
if(l==r)return sum[x];
int mid=(l+r)>>;
if(p<=mid)return ask(ls[x],l,mid,p);
return sum[ls[x]]+ask(rs[x],mid+,r,p);
}
ll query(int x,int p)//<=p 的个数
{
ll ret=;
for(;x;x-=(x&-x)) ret+=ask(rt[x],,n,p);
return ret;
}
ll pre(int x,int p){return query(p,n)-query(p,x);}
ll suf(int x,int p){return query(n,x)-query(p,x);}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x;i<=n;i++)
{
scanf("%d",&x); pos[x]=i;
ans+=getsum(n)-getsum(x);
add(x); insert(i,x,);
}
for(int i=,x;i<=m;i++)
{
printf("%lld\n",ans); scanf("%d",&x);
ans-=pre(x,pos[x])+suf(x,pos[x]);
insert(pos[x],x,-);
}
return ;
}

洛谷P1393,离散化一下即可。(通过数喜+1)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=4e4+,maxm=maxn*;
int n,m,t[maxn],rt[maxn],ls[maxm],rs[maxm],sum[maxm],cnt,tot;
ll ans,a[maxn],b[maxn];
ll getsum(int x)
{
ll ret=;
for(;x;x-=(x&-x)) ret+=t[x];
return ret;
}
void add(int x)
{
for(;x<=n;x+=(x&-x)) t[x]++;
}
void update(int &x,int l,int r,int p,int v)
{
if(!x)x=++cnt; sum[x]+=v;
if(l==r)return;
int mid=(l+r)>>;
if(p<=mid)update(ls[x],l,mid,p,v);
else update(rs[x],mid+,r,p,v);
}
void insert(int x,int p,int v)
{
for(;x<=n;x+=(x&-x)) update(rt[x],,n,p,v);
}
ll ask(int x,int l,int r,int p)
{
if(l==r)return sum[x];
int mid=(l+r)>>;
if(p<=mid)return ask(ls[x],l,mid,p);
return sum[ls[x]]+ask(rs[x],mid+,r,p);
}
ll query(int x,int p)//<=p 的个数
{
ll ret=;
for(;x;x-=(x&-x)) ret+=ask(rt[x],,n,p);
return ret;
}
ll pre(int x,int p){return query(p,n)-query(p,x);}
ll suf(int x,int p){return query(n,x)-query(p,x);}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%lld",&a[i]),b[i]=a[i];
sort(b+,b+n+);
tot=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++) a[i]=lower_bound(b+,b+tot+,a[i])-b;
for(int i=;i<=n;i++)
{
ans+=getsum(n)-getsum(a[i]);
add(a[i]); insert(i,a[i],);
}
for(int i=,k;i<=m;i++)
{
printf("%lld ",ans); scanf("%d",&k);
ans-=pre(a[k],k)+suf(a[k],k);
insert(k,a[k],-);
}
printf("%lld\n",ans);
return ;
}

bzoj3295 洛谷P3157、1393 动态逆序对——树套树的更多相关文章

  1. 洛谷 P3157 [CQOI2011]动态逆序对 解题报告

    P3157 [CQOI2011]动态逆序对 题目描述 对于序列\(A\),它的逆序对数定义为满足\(i<j\),且\(A_i>A_j\)的数对\((i,j)\)的个数.给\(1\)到\(n ...

  2. 洛谷 P3157 [CQOI2011]动态逆序对(树套树)

    题面 luogu 题解 树套树(树状数组套动态开点线段树) 静态使用树状数组求逆序对就不多说了 用线段树代替树状数组,外面套树状数组统计每个点逆序对数量 设 \(t1[i]\)为\(i\)前面有多少个 ...

  3. 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治

    题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...

  4. 洛谷P3157 [CQOI2011]动态逆序对

    题目大意: 给定\(1\)到\(n\)的一个排列,按照给定顺序依次删除\(m\)个元素,计算每个元素删除之前整个序列的逆序对数量 基本套路:删边变加边 那么我们不就是求满足\(pos_i<pos ...

  5. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

  6. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  7. P3157 [CQOI2011]动态逆序对

    P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...

  8. P3157 [CQOI2011]动态逆序对 (CDQ解决三维偏序问题)

    P3157 [CQOI2011]动态逆序对 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任 ...

  9. BZOJ_3295_[Cqoi2011]动态逆序对_CDQ分治+树状数组

    BZOJ_3295_[Cqoi2011]动态逆序对_CDQ分治+树状数组 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一 ...

随机推荐

  1. mysql 替换数据库字段内容

    去掉数据库字段单引号 update company_info set company=REPLACE(company,"'","");

  2. PHP:验证手机号码合法性

    文章来源:http://www.cnblogs.com/hello-tl/p/7592333.html /** * [verifyPhone description] 效验手机号码合法性 * @par ...

  3. 理解ZAB协议

    ZAB协议 介绍 1.zab协议是为分布式协调服务zookpeer专门设计的一种支持崩溃恢复的原子广播协议 2.在zookeeper中主要依赖ZAB协议来实现数据一致性,基于该协议zk实现了一种主备模 ...

  4. 【转】 Java中的IO整理

    写在前面:本文章基本覆盖了java IO的全部内容,java新IO没有涉及,因为我想和这个分开,以突出那个的重要性,新IO哪一篇文章还没有开始写,估计很快就能和大家见面.照旧,文章依旧以例子为主,因为 ...

  5. hdu 1698区间延迟更新

    #include<stdio.h> #define N 100100 struct node { int x,y,yanchi; }a[N*4];//注意数组范围 void build(i ...

  6. openjudge7627 鸡蛋的硬度

    描述 最近XX公司举办了一个奇怪的比赛:鸡蛋硬度之王争霸赛.参赛者是来自世 界各地的母鸡,比赛的内容是看谁下的蛋最硬,更奇怪的是XX公司并不使用什么精密仪器来测量蛋的硬度,他们采用了一种最老土的办法- ...

  7. laravel toggle方法

    toggle方法主要用于多对多关系中,attach detach 比如点赞 收藏 1.user表 2.post表 title content 3.中间表 favoriate user_id post_ ...

  8. 基于Wi-Fi的HID注射器,利用WHID攻击实验

    WHID代表基于 Wi-Fi 的 HID 注射器,即对 HID 攻击进行无线化攻击的一种注入工具. 实验攻击原理如下图: 攻击者使用ESP8266作为AP,在自己的电脑创建客户端连接AP.在客户端键入 ...

  9. java编程思想-复用类

    /* 一个文件中只能有一个public类 并且此public类必须与文件名相同 */ class WaterSource { private String s; WaterSource() { Sys ...

  10. Mali GPU OpenGL ES 应用性能优化--基本方法

    1. 经常使用优化工具 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXlBcnJvdw==/font/5a6L5L2T/fontsize/400/fil ...