这个题就是动态偏序对,每次操作做两个删除两个插入就好了。

#include<cstdio>
#include<iostream>
#include<cstring>
#define MAXN 100010
using namespace std;
typedef long long LL;
typedef double D;
const D a=0.756;
LL ans;
struct ScapeGoat_Tree
{
ScapeGoat_Tree *ch[];
int key,size,cover,ex;
bool bad()
{
return cover*a+<ch[]->cover||cover*a+<ch[]->cover;
}
void pushup()
{
size=ch[]->size+ch[]->size+ex;
cover=ch[]->cover+ch[]->cover+;
}
}*null,*stack[(MAXN<<)+],pool[(MAXN<<)+],*lst[(MAXN<<)+];
int top,len;
inline void Init()
{
null=pool;
null->ch[]=null->ch[]=null;
null->key=null->size=null->cover=null->ex=;
for(int i=;i<(MAXN<<);i++)stack[++top]=pool+i;
}
inline ScapeGoat_Tree *New(int key)
{
ScapeGoat_Tree *p=stack[top--];
p->ch[]=p->ch[]=null;
p->key=key;
p->size=p->ex=p->cover=;
return p;
}
struct Tree
{
Tree *ch[];
int mid,l,r;
ScapeGoat_Tree *root;
Tree(){ch[]=ch[]=NULL;mid=l=r=;root=null;}
void* operator new(size_t size);
}*root,*C,*mempool;
void* Tree :: operator new(size_t size)
{
if(C==mempool)
{
C=new Tree[(<<)+];
mempool=C+(<<)+;
}
C->root=null;
return C++;
}
void travel(ScapeGoat_Tree *p)
{
if(p==null)return;
travel(p->ch[]);
if(p->ex)lst[++len]=p;
else stack[++top]=p;
travel(p->ch[]);
}
ScapeGoat_Tree *divide(int l,int r)
{
if(l>r)return null;
int mid=(l+r)>>;
lst[mid]->ch[]=divide(l,mid-);
lst[mid]->ch[]=divide(mid+,r);
lst[mid]->pushup();
return lst[mid];
}
inline void rebuild(ScapeGoat_Tree *&p)
{
len=;
travel(p);
p=divide(,len);
}
ScapeGoat_Tree **insert(ScapeGoat_Tree *&p,int key)
{
if(p==null )
{
p=New(key);
return &null;
}
p->size++;
p->cover++;
ScapeGoat_Tree **ret=insert(p->ch[p->key<=key],key);
if(p->bad())ret=&p;
return ret;
}
inline void Insert(ScapeGoat_Tree *&Root,int key)
{
ScapeGoat_Tree **p=insert(Root,key);
if(*p!=null )rebuild(*p);
}
inline int Rank_Max(ScapeGoat_Tree *Root,int key)
{
ScapeGoat_Tree *now=Root;
int ret=;
while(now!=null )
if(now->key<=key)
now=now->ch[];
else
ret+=now->ch[]->size+now->ex,now=now->ch[];
return ret;
}
inline int Rank_Min(ScapeGoat_Tree *Root,int key)
{
ScapeGoat_Tree *now=Root;
int ret=;
while(now!=null )
if(now->key>=key)
now=now->ch[];
else
ret+=now->ch[]->size+now->ex,now=now->ch[];
return ret;
}
void del(ScapeGoat_Tree *p,int k)
{
p->size--;
if(p->ex&&p->ch[]->size+==k)
{
p->ex=;
return;
}
if(p->ch[]->size>=k) del(p->ch[],k);
else del(p->ch[],k-p->ch[]->size-p->ex);
}
inline void Del(ScapeGoat_Tree *&Root,int key)
{
del(Root,Rank_Min(Root,key)+);
if(Root->size<Root->cover*a)rebuild(Root);
}
int n,m,pos[MAXN];
void build(Tree *p)
{
p->mid=(p->l+p->r)>>;
if(p->l==p->r)return;
p->ch[]=new Tree;
p->ch[]->l=p->l;
p->ch[]->r=p->mid;
p->ch[]=new Tree;
p->ch[]->l=p->mid+;
p->ch[]->r=p->r;
build(p->ch[]);
build(p->ch[]);
}
void Ins(Tree *p,int key,int aim)
{
Insert(p->root,key);
if(p->l==p->r)return;
Ins(p->ch[p->mid<aim],key,aim);
}
int query_Max(int l,int r,int key,Tree *p)
{
if(l<=p->l&&p->r<=r)
return Rank_Max(p->root,key);
int tmp=;
if(l<=p->mid)tmp+=query_Max(l,r,key,p->ch[]);
if(p->mid<r)tmp+=query_Max(l,r,key,p->ch[]);
return tmp;
}
int query_Min(int l,int r,int key,Tree *p)
{
if(l<=p->l&&p->r<=r)
return Rank_Min(p->root,key);
int tmp=;
if(l<=p->mid)tmp+=query_Min(l,r,key,p->ch[]);
if(p->mid<r)tmp+=query_Min(l,r,key,p->ch[]);
return tmp;
}
void Delete(Tree *p,int key,int aim)
{
Del(p->root,key);
if(p->l==p->r)return;
Delete(p->ch[p->mid<aim],key,aim);
}
int main()
{
//freopen("nt2011_queue.in","r",stdin);
//freopen("nt2011_queue.out","w",stdout);
Init();
scanf("%d",&n);
root=new Tree;
root->l=;
root->r=n;
build(root);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
pos[i]=x;
Ins(root,x,i);
if(i!=)ans+=query_Max(,i-,x,root);
}
scanf("%d",&m);
for(int i=;i<=m;i++)
{
printf("%lld\n",ans);
int x,y;
scanf("%d%d",&x,&y);
if(x!=) ans-=query_Max(,x-,pos[x],root);
if(x!=n) ans-=query_Min(x+,n,pos[x],root);
Delete(root,pos[x],x);
if(y!=) ans-=query_Max(,y-,pos[y],root);
if(y!=n) ans-=query_Min(y+,n,pos[y],root);
Delete(root,pos[y],y);
swap(pos[x],pos[y]);
Ins(root,pos[x],x);
if(x!=) ans+=query_Max(,x-,pos[x],root);
if(x!=n) ans+=query_Min(x+,n,pos[x],root);
Ins(root,pos[y],y);
if(y!=) ans+=query_Max(,y-,pos[y],root);
if(y!=n) ans+=query_Min(y+,n,pos[y],root);
}
printf("%lld\n",ans);
return ;
}

【bzoj2141】排队 [国家集训队2011]排队(魏铭) 树套树 线段树套替罪羊树的更多相关文章

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

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...

  2. COGS1871 [国家集训队2011]排队(魏铭)

    bzoj:http://www.lydsy.com/JudgeOnline/problem.php?id=2141 cogs:http://cogs.pro:8080/cogs/problem/pro ...

  3. AC日记——[国家集训队2011]旅游(宋方睿) cogs 1867

    [国家集训队2011]旅游(宋方睿) 思路: 树链剖分,边权转点权: 线段树维护三个东西,sum,max,min: 当一个区间变成相反数时,sum=-sum,max=-min,min=-max: 来, ...

  4. cogs 1901. [国家集训队2011]数颜色

    Cogs 1901. [国家集训队2011]数颜色 ★★★   输入文件:nt2011_color.in   输出文件:nt2011_color.out   简单对比时间限制:0.6 s   内存限制 ...

  5. BZOJ 2150 cogs 1861 [国家集训队2011]部落战争

    题目描述 lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住.lanzerb把 ...

  6. happiness[国家集训队2011(吴确)]

    [试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...

  7. COGS1882 [国家集训队2011]单选错位

    ★   输入文件:nt2011_exp.in   输出文件:nt2011_exp.out   简单对比时间限制:1 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题 ...

  8. 1893. [国家集训队2011]等差子序列(bitset)

    ★★   输入文件:nt2011_sequence.in   输出文件:nt2011_sequence.out   简单对比时间限制:0.3 s   内存限制:512 MB [试题来源] 2011中国 ...

  9. bzoj2144 【国家集训队2011】跳跳棋

    Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...

随机推荐

  1. JAVA Web 项目中用到的技术

    JSPServletTomcatMySQL MavenSpringMVCHibernatejQueryBootstrapAngularJSBootStrap Table 下边两个是移动APP开发要用到 ...

  2. List集合中的对象比较,取出不同对象

    今天在做金碟系统与我们系统的对接的时候需要做一个客户同步 在同步时,需要比较对象,对查询出的数据库的数据进行比较 for(int i=0;i<list2.size();i++){ if(! li ...

  3. pwa学习笔记--简介

    1. 介绍 Progressive Web App , (渐进式增强 WEB 应用) 简称 PWA ,是提升WebApp的体验的一种新方法,能给用户原生应用的体验. PWA 本质上是 Web App ...

  4. Java线程和多线程(九)——死锁

    Java中的死锁指的就是一种多于两个线程永远阻塞的特殊状况.Java中的死锁状态至少需要多于两个线程以及资源的时候才会产生.这里,我写了一个产生死锁的程序,并且讲下如何分析死锁. 首先来看一下产生死锁 ...

  5. LeetCode:19. Remove Nth Node From End of List(Medium)

    1. 原题链接 https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/ 2. 题目要求 给出一个链表,请 ...

  6. malloc函数分配失败处理的严重性

    本次在实际测试情况下,发现程序无缘无故的异常,导致看门狗超时复位,经过排查是malloc函数分配失败的时候,依然对指针进行了操作,导致异常.以前没重视这个问题是因为,总觉的malloc基本都会成功的, ...

  7. 【廖雪峰老师python教程】——filter/sorted

    filter Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然 ...

  8. HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)

    Problem Description Japanese Mahjong is a four-player game. The game needs four people to sit around ...

  9. 完整Android开发基础入门博客专栏

    博客地址:http://www.runoob.com/w3cnote/android-tutorial-contents.html

  10. uva 11526 H(n) (数论)

    转载自 http://blog.csdn.net/synapse7/article/details/12873437 这道题我自己做的时候没有想到好的优化方法,提交的时候借鉴这篇文章的内容,转载如下: ...