题目: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分治的更多相关文章

  1. 【洛谷3157】[CQOI2011] 动态逆序对(CDQ分治)

    点此看题面 大致题意: 给你一个从\(1\)到\(n\)的排列,问你每次删去一个元素后剩余的逆序对个数. 关于\(80\)分的树套树 为了练树套树,我找到了这道题目. 但悲剧的是,我的 线段树套\(T ...

  2. BZOJ 3295:[Cqoi2011]动态逆序对(三维偏序 CDQ分治+树状数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3295 题意:简单明了. 思路:终于好像有点明白CDQ分治处理三维偏序了.把删除操作看作是插入操作,那 ...

  3. bzoj3295 洛谷P3157、1393 动态逆序对——树套树

    题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...

  4. [bzoj3295][Cqoi2011]动态逆序对_主席树

    动态逆序对 bzoj-3295 Cqoi-2011 题目大意:题目链接. 注释:略. 想法:直接建立主席树. 由于是一个一个删除,所以我们先拿建立好的root[n]的权值线段树先把总逆序对求出来,接着 ...

  5. [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)

    [BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...

  6. BZOJ 3295: [Cqoi2011]动态逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3865  Solved: 1298[Submit][Sta ...

  7. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

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

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

  9. bzoj千题计划146:bzoj3295: [Cqoi2011]动态逆序对

    http://www.lydsy.com/JudgeOnline/problem.php?id=3295 正着删除看做倒着添加 对答案有贡献的数对满足以下3个条件: 出现时间:i<=j 权值大小 ...

随机推荐

  1. Linux图形化界面下使用命令进行截图的方法

    以前在LINUX里面截图都是直接按print screen键或者 alt + print screen. 但是print screen是整个屏幕, alt + print screen是当前窗口. 想 ...

  2. get the request body of all quests before handle it

    https://stackoverflow.com/questions/23660340/need-to-log-asp-net-webapi-2-request-and-response-body- ...

  3. ls存在的文件,不能操作

    bash-4.2# pwd/oracle/product/10.2.0/db_1/network/adminbash-4.2# lssqlnet.ora                 libnrad ...

  4. timer使用方法

    , HEART_EXPIRE}; , }; /* 第一次调用要多长时间 */ struct itimerval it; it.it_interval = tv_interval; it.it_valu ...

  5. 有谁知道什么工具测试IOS手机上APP的性能软件啊?

    有谁知道什么工具测试IOS手机上APP的性能软件啊?

  6. TF卡.购买(20180925)

    1.准备买 2个 一个 用于 老的手机"红米Note",一个用于现在我的手机"红米Note4X". 之前,这2个手机都是用的 那个坏掉的64g的tf卡 2.刚问 ...

  7. scala学习手记39 - 模式匹配

    在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串. 在scala中也有类似的模式匹配语句,即ma ...

  8. 5.8 页面对象(Page Object)模式

    页面对象(Page Object)模式是目前自动化测试领域普遍使用的设计模式之一,此模式可以大大提高测试代码的复用率,提高测试脚本的编写效率和维护效率,是中级自动化测试工程师的必备技能之一. 1.页面 ...

  9. LightOJ - 1341唯一分解定理

    唯一分解定理 先分解面积,然后除2,再减去面积%长度==0的情况,注意毯子不能是正方形 #include<map> #include<set> #include<cmat ...

  10. poj1274

    题解: 二分图匹配 裸题匈牙利匹配 代码: #include<cstdio> #include<cstring> #include<cmath> #include& ...