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 权值大小 ...
随机推荐
- MySQLdump增量备份、完全备份与恢复
在数据库表丢失或损坏的情况下,备份你的数据库是很重要的.如果发生系统崩溃,你肯定想能够将你的表尽可能丢失最少的数据恢复到崩溃发生时的状态.场景:每周日执行一次完全备份,每天下午1点执行MySQLdum ...
- java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
1.问题描述: 对于创建的springboot项目,通过启动类启动,访问没问题,但打成war部署到tomcat上启动报错,如下: 严重: ContainerBase.addChild: start: ...
- Servlet容器初始化IOC容器
<!-- ServletContext参数,配置Ioc容器的xml文件名 --> <context-param> <param-name>contextConfig ...
- Luogu-3250 [HNOI2016]网络
Luogu-3250 [HNOI2016]网络 题面 Luogu-3250 题解 CDQ分治...这个应该算是整体二分吧 二分重要度,按照时间从小到大加入大于重要度的边 对于一个询问,如果经过这个点的 ...
- 数组排序array_multisort
array_multisort --对多个数组或者多维数组进行排序[参考:secure.php.net] 说明: bool array_multisort ( array &$array1 [ ...
- JavaScript字符串转换为变量名
1.将一个字符串转换为变量名 [javascript] view plain copy print? function string_to_name(string){ let _name = 'var ...
- CodeChef FORESTGA 二分
Forest Gathering Problem code: FORESTGA Tweet ALL SUBMISSIONS All submissions for this problem ...
- Eclipse下建立简单JNI程序实现返回double类型
在Eclipse下生成时要注意,由于通常是在package里面添加类,而非像单独建立工程时独立添加,所以,在编译的时候,都需要进入包所在的文件夹, javac 包名.类名 这样的形式来编译,同理,ja ...
- WPF的外观装饰类——Border
public class Border : System.Windows.Controls.Decorator 说明:在另一个元素的周围绘制边框.背景或同时绘制二者.
- Eclipse中Preference打开后找不到Server项解决方案。
该解决方案是假设你已经安装好了JDK,tomcat,eclipse,突然在Eclipse的配置时找不到选择菜单栏中的window——preferences-server——runtime enviro ...