P3157 [CQOI2011]动态逆序对 cdq分治
思路:cdq分治(主席树还没看)
提交:\(2\)次(窝\(CE\)了)
题解:
记录询问:操作的时间\(t_i\)(初始存在的数记时间为\(0\)),操作的位置\(p_i\),操作的值\(vl_i\),操作的类型(\(-1\ or\ 1\))。
记录答案:每次只算出这次操作造成的影响并累加到操作时间上(所以第\(0\)时刻算出的即为初始逆序对),做一个前缀和即可求出某一时刻的答案。
如何计算贡献:考虑一个数所形成的逆序对:
- \(t_i<t_j\)且\(p_i<p_j\)且\(vl_i>vl_j\)
- \(t_i<t_j\)且\(p_i>p_j\)且\(vl_i<vl_j\)
所以我们需要扫两次:从前往后扫(第一种)然后从后往前扫(第二种)
// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define R register int
#define ll long long
using namespace std;
namespace Fread {
static char buff[1>>15],*S=buff,*T=buff;
inline char gc() {
#ifdef JACK
return getchar();
#else
return (S==T&&(T=(S=buff)+fread(buff,1,1<<15,stdin),S==T)?EOF:*S++);
#endif
}
inline int g() {
R ret=0,fix=1; register char ch; while(!isdigit(ch=gc())) fix=ch=='-'?-1:fix;
do ret=ret*10+(ch^48); while(isdigit(ch=gc())); return ret*fix;
}
} using Fread::gc; using Fread::g;
namespace Luitaryi {
const int N=150010;
int n,m,c[N],p[N];
ll ans[N];
struct node {int t,p,vl,w,rk;
inline bool operator <(const node& that) const {return p<that.p;}
}a[N],tmp[N];
inline void add(int p,int d) {for(;p<=n;p+=p&-p) c[p]+=d;}
inline int query(int p) {R ret=0; for(;p;p-=p&-p) ret+=c[p]; return ret;}
inline void solve(int l,int r) {
if(l==r) return; R md=l+r>>1;
solve(l,md),solve(md+1,r);
R j=l,i=md+1; for(;i<=r;++i) {
while(j<=md&&a[j].p<=a[i].p) add(a[j].vl,a[j].w),++j;
ans[a[i].t]+=a[i].w*(query(n)-query(a[i].vl));
} for(R i=l;i<j;++i) add(a[i].vl,-a[i].w);
j=md,i=r; for(;i>md;--i) {
while(j>=l&&a[j].p>=a[i].p) add(a[j].vl,a[j].w),--j;
ans[a[i].t]+=a[i].w*query(a[i].vl-1);
} for(R i=md;i>j;--i) add(a[i].vl,-a[i].w);
merge(a+l,a+md+1,a+md+1,a+r+1,tmp+l);
memcpy(a+l,tmp+l,sizeof(node)*(r-l+1));
}
inline void main() {
n=g(),m=g();
for(R i=1;i<=n;++i) a[i].w=1,a[i].vl=g(),a[i].p=i,a[i].t=0,a[i].rk=i,p[a[i].vl]=i;
for(R i=n+1;i<=n+m;++i) a[i].w=-1,a[i].vl=g(),a[i].p=p[a[i].vl],a[i].t=i-n,a[i].rk=i;
solve(1,n+m);
for(R i=1;i<=m;++i) ans[i]+=ans[i-1];
for(R i=0;i<m;++i) printf("%lld\n",ans[i]);
}
}
signed main() {
Luitaryi::main(); return 0;
}
2019.07.31
还有100天