zoukankan      html  css  js  c++  java
  • BZOJ 3295: [Cqoi2011]动态逆序对 cdq分治

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

    这个妹妹我曾见过的~~~

    之前应该在校内oj写了,似乎还写过题解?发现没写博客就重新水一遍代码水一篇博客好了。

    把找逆序对的过程想成一个一个往里塞数字然后找每个数字可以组成的逆序对,把最后要去掉的几个也想成往里塞,所以加一个时间维度用cdq求三维偏序。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 #define LL long long
     9 #define pa pair<int,int>
    10 const int maxn=100010;
    11 const LL minf=(LL)5e17;
    12 int n,m;
    13 struct nod{
    14     int t,id,v;LL ans;
    15 }a[maxn];
    16 int b[maxn]={},vis[maxn]={};
    17 LL t[maxn]={}; int sta[maxn]={},tai=0;
    18 priority_queue< pa , vector< pa > , greater< pa > >q[2];
    19 
    20 inline void addt(int x,int v){ while(x<=n){ t[x]+=v; x+=(x&-x); } }
    21 inline LL gett(int x){ LL tsn=0; while(x){ tsn+=t[x]; x-=(x&-x); } return tsn; }
    22 bool mcmp1(nod aa,nod bb){
    23     if(aa.id!=bb.id)return aa.id<bb.id;
    24     return aa.t<bb.t;
    25 }
    26 bool mcmp2(nod aa,nod bb){
    27     if(aa.t!=bb.t)return aa.t<bb.t;
    28     return aa.id<bb.id;
    29 }
    30 void doit(int l,int r){
    31     if(l==r)return;
    32     int mid=(l+r)/2;
    33     doit(l,mid); doit(mid+1,r);
    34     //x被查找y查找
    35     for(int i=l;i<=mid;i++)q[0].push(make_pair(a[i].t,i));
    36     for(int i=mid+1;i<=r;i++)q[1].push(make_pair(a[i].t,i));
    37     tai=0;
    38     while(!q[1].empty()){
    39         pa y=q[1].top(); q[1].pop();
    40         if(q[0].empty()){a[y.second].ans+=gett(n)-gett(a[y.second].v);continue;} pa x=q[0].top();
    41         while(x.first<=y.first){
    42             addt(a[x.second].v,1); sta[++tai]=a[x.second].v;
    43             q[0].pop(); if(q[0].empty())break; x=q[0].top();
    44         }a[y.second].ans+=gett(n)-gett(a[y.second].v);
    45     }
    46     while(!q[0].empty())q[0].pop();
    47     for(int i=1;i<=tai;i++)addt(sta[i],-1);
    48     
    49     for(int i=l;i<=mid;i++)q[0].push(make_pair(a[i].t,i));
    50     for(int i=mid+1;i<=r;i++)q[1].push(make_pair(a[i].t,i));
    51     tai=0;
    52     while(!q[0].empty()){
    53         pa y=q[0].top(); q[0].pop();
    54         if(q[1].empty()){a[y.second].ans+=gett(a[y.second].v-1);continue;} pa x=q[1].top();
    55         while(x.first<=y.first){
    56             addt(a[x.second].v,1); sta[++tai]=a[x.second].v;
    57             q[1].pop(); if(q[1].empty())break; x=q[1].top();
    58         }a[y.second].ans+=gett(a[y.second].v-1);
    59     }
    60     while(!q[1].empty())q[1].pop();
    61     for(int i=1;i<=tai;i++)addt(sta[i],-1);
    62 }
    63 int main(){
    64     scanf("%d%d",&n,&m);
    65     for(int i=1;i<=n;i++){scanf("%d",&a[i].v);a[i].id=i;a[i].t=i;vis[a[i].v]=i;}
    66     for(int i=1;i<=m;i++){scanf("%d",&b[i]);a[vis[b[i]]].t=n+m+1-i;}
    67     sort(a+1,a+1+n,mcmp1); doit(1,n);
    68     sort(a+1,a+1+n,mcmp2);
    69     for(int i=2;i<=n;i++)a[i].ans+=a[i-1].ans;
    70     for(int i=1;i<=m;i++)printf("%lld
    ",a[n-i+1].ans);
    71     return 0;
    72 }
    View Code

  • 相关阅读:
    在.netframework 4.5.2项目上集成identityserver4的登录功能
    Elasticsearch学习笔记之—测试查询分词器的分词结果
    asp.net core mysql 错误提示:Out of memory (Needed***
    Elasticsearch学习笔记之— excludes的高级用法
    正则表达式(.*?)
    WPF里实现imageButton的步骤
    Elasticsearch学习笔记之—wildcard、fuzzy、regexp、prefix
    Elasticsearch学习笔记之—数据范围查询
    工具小方法
    lambda表达式
  • 原文地址:https://www.cnblogs.com/137shoebills/p/9060496.html
Copyright © 2011-2022 走看看