• 【bzoj2141】排队 [国家集训队2011]排队(树套树)


    题目描述

    排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。

    红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足i<j且hi>hj的(i,j)数量。

    幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。

    题解

      新技能get

      树状数组+动态开点线段树

      具体看代码(因为我讲不来)

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=20005;
     7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     8 char buf[1<<21],*p1=buf,*p2=buf;
     9 inline int read(){
    10     #define num ch-'0'
    11     char ch;bool flag=0;int res;
    12     while(!isdigit(ch=getc()))
    13     (ch=='-')&&(flag=true);
    14     for(res=num;isdigit(ch=getc());res=res*10+num);
    15     (flag)&&(res=-res);
    16     #undef num
    17     return res;
    18 }
    19 char sr[1<<21],z[20];int C=-1,Z;
    20 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    21 inline void print(int x){
    22     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    23     while(z[++Z]=x%10+48,x/=10);
    24     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    25 }
    26 struct node{
    27     int v,id;
    28     inline bool operator <(const node &b)const{return v<b.v;}
    29 }a[N];
    30 int n,m,x,y,tot,ans,b[N],c[N];
    31 inline void add(int x){
    32     for(;x<=n;x+=x&-x) ++c[x];
    33 }
    34 inline int sum(int x){
    35     int res=0;
    36     for(;x;x-=x&-x) res+=c[x];
    37     return res;
    38 }
    39 int cnt,rt[N],v[N*400],L[N*400],R[N*400];
    40 void insert(int &u,int l,int r,int x,int k){
    41     if(!u) u=++cnt;v[u]+=k;
    42     if(l==r) return;int mid=l+r>>1;
    43     if(x<=mid) insert(L[u],l,mid,x,k);
    44     else insert(R[u],mid+1,r,x,k);
    45 }
    46 void push(int x,int y,int k){
    47     for(;x<=n;x+=x&-x) insert(rt[x],1,n,y,k);
    48 }
    49 int Query(int u,int l,int r,int ql,int qr){
    50     if(!u) return 0;
    51     if(ql<=l&&qr>=r) return v[u];
    52     int mid=l+r>>1;
    53     int res=0;
    54     if(ql<=mid) res+=Query(L[u],l,mid,ql,qr);
    55     if(qr>mid) res+=Query(R[u],mid+1,r,ql,qr);
    56     return res;
    57 }
    58 int query(int l,int r,int ql,int qr){
    59     if(l>r||ql>qr) return 0;
    60     int sum=0;--l;
    61     for(;r;r-=r&-r) sum+=Query(rt[r],1,n,ql,qr);
    62     for(;l;l-=l&-l) sum-=Query(rt[l],1,n,ql,qr);
    63     return sum;
    64 }
    65 int main(){
    66     //freopen("testdata.in","r",stdin);
    67     n=read();
    68     for(int i=1;i<=n;++i) a[i]=(node){read(),i};
    69     sort(a+1,a+1+n);
    70     for(int i=1;i<=n;++i){
    71         if(a[i].v!=a[i-1].v) ++tot;
    72         b[a[i].id]=tot;
    73     }
    74     for(int i=n;i;--i) ans+=sum(b[i]-1),add(b[i]);
    75     for(int i=1;i<=n;++i) push(i,b[i],1);
    76     m=read(),print(ans);
    77     while(m--){
    78         int x=read(),y=read();
    79         if(x>y) swap(x,y);
    80         ans+=query(x+1,y-1,1,b[y]-1);
    81         ans-=query(x+1,y-1,b[y]+1,n);
    82         ans+=query(x+1,y-1,b[x]+1,n);
    83         ans-=query(x+1,y-1,1,b[x]-1);
    84         if(b[x]>b[y]) --ans;
    85         if(b[x]<b[y]) ++ans;
    86         push(x,b[x],-1),push(y,b[y],-1);
    87         push(y,b[x],1),push(x,b[y],1);
    88         swap(b[x],b[y]);
    89         print(ans);
    90     }
    91     Ot();
    92     return 0;
    93 }
  • 相关阅读:
    VS2010插件及快捷键设置
    在Windows程序中启用console输出-2016.01.04
    使用VAssistX给文件和函数添加注释-2015.12.31
    windows在远程桌面连接中使用命令行参数
    windows网络编程-2015.12.29
    grep使用
    linux程序调试常用命令
    vim使用笔记
    infusion度量金字塔数据解释
    MVc Forms Membership rolemanage 角色权限验证管理
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9560383.html
Copyright © 2020-2023  润新知