【bzoj2141】排队 [国家集训队2011]排队(魏铭) 树套树 线段树套替罪羊树
这个题就是动态偏序对,每次操作做两个删除两个插入就好了。
#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]排队(魏铭) 树套树 线段树套替罪羊树的更多相关文章
- 【bzoj2141】排队 [国家集训队2011]排队(树套树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- COGS1871 [国家集训队2011]排队(魏铭)
bzoj:http://www.lydsy.com/JudgeOnline/problem.php?id=2141 cogs:http://cogs.pro:8080/cogs/problem/pro ...
- AC日记——[国家集训队2011]旅游(宋方睿) cogs 1867
[国家集训队2011]旅游(宋方睿) 思路: 树链剖分,边权转点权: 线段树维护三个东西,sum,max,min: 当一个区间变成相反数时,sum=-sum,max=-min,min=-max: 来, ...
- cogs 1901. [国家集训队2011]数颜色
Cogs 1901. [国家集训队2011]数颜色 ★★★ 输入文件:nt2011_color.in 输出文件:nt2011_color.out 简单对比时间限制:0.6 s 内存限制 ...
- BZOJ 2150 cogs 1861 [国家集训队2011]部落战争
题目描述 lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住.lanzerb把 ...
- happiness[国家集训队2011(吴确)]
[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...
- COGS1882 [国家集训队2011]单选错位
★ 输入文件:nt2011_exp.in 输出文件:nt2011_exp.out 简单对比时间限制:1 s 内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题 ...
- 1893. [国家集训队2011]等差子序列(bitset)
★★ 输入文件:nt2011_sequence.in 输出文件:nt2011_sequence.out 简单对比时间限制:0.3 s 内存限制:512 MB [试题来源] 2011中国 ...
- bzoj2144 【国家集训队2011】跳跳棋
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
随机推荐
- JavaSE 第二次学习随笔(五)
/* * 中文乱码出现的情况研究 * 注意点:乱码解决的办法是再编码再解码 * 但是如果是编码出错了,无法解决.如果是解码出错了,可以利用再编码再解码 * * * 编码 解码 结果 * GBK utf ...
- ruby $LOAD_PATH及类加载
$LOAD_PATH $LOAD_PATH 指的是Ruby读取外部文件的一个环境变量,其实和windows的环境变量是一个概念.Ruby会在这个环境变量的路径中读取需要require的文件,如果在环境 ...
- C语言实例解析精粹学习笔记——39(简单的文本编辑器)
实例说明: 编辑一个简单的单行文本编辑器,编辑命令有以下几种:(E.Q.R.I.D) 只有自己在完全空白的情况下编写出来的程序,才是真正自己会的程序,现在所做的,不过是程序的搬运工,把书上的程序搬到网 ...
- Windows10 快捷键
windows 10快捷键: F1 打开帮助 F2 重命名 F3 打开搜索文件和文件夹 F4 打开地址栏常用的地址 F5 刷新 F11 全屏 选择文件和内容: shift + 上下左右键选择连续的 ...
- FPGA算法学习(1) -- Cordic(圆周系统之旋转模式)
三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...
- nyoj 525 一道水题【字符串(分割)】
参考:https://blog.csdn.net/dxx_111/article/details/48154687 #include <iostream> #include <cst ...
- 初步学习pg_control文件之五
接前文 初步学习pg_control文件之四,继续看何时出现 DB_IN_CRASH_RECOVERY: 看下面代码就比较清楚了:如果对 InArchiveRecovery 判断值为假,而且 读取出 ...
- Ubuntu中搭建Hadoop集群(简记)
stp1:在Vmware虚拟机上创建Ubantu.2环境 步骤:文件—>新建虚拟机—>典型(下一步)—>下一步——>位置(不建议放c盘,文件地址一定要全英文)—>下一步— ...
- 【廖雪峰老师python教程】——装饰器
装饰器 # 一个函数装饰器的列子 def log(func): def wrapper(*args,**kwargs): print('Name=%s'%func.__name__) return f ...
- MySQL训练营03
[任务四] #任务时间# 请于4月6日22:00前完成,在[打卡表格]处打卡.逾期尚未打卡的会被清退. 4.1 MySQL 实战 #学习内容# 数据导入导出 将之前创建的任意一张MySQL表导出,且是 ...