bzoj 2120 数颜色 树状数组套平衡树
2015-12-01 18:28
411 查看
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2120
写了一整天树状数组套平衡树,结果看题解这是一道暴力就能水过的题T_T
然而最后跑起来还是蛮快的,这点我很欣慰!
最后还是说树套树,因为这道题是从第L支笔到第R支笔中共有多少种不同的颜色,第i支笔我们可以记录前一个与它颜色相同的笔last和后一个与它颜色相同的笔next,将last加入平衡树。
这样,询问L到R中不同的颜色的时候,查找L到R中多少支笔的last小于L,即为所求。
修改时要麻烦一些,首先删掉f[x]位置的last,之后将f[x]位置修改为颜色y,之后再将f[x]位置加入平衡树,大概意思还是看代码吧。
ps:build函数是将一个数加入平衡树,change函数是从平衡树中删除一个数
写了一整天树状数组套平衡树,结果看题解这是一道暴力就能水过的题T_T
然而最后跑起来还是蛮快的,这点我很欣慰!
最后还是说树套树,因为这道题是从第L支笔到第R支笔中共有多少种不同的颜色,第i支笔我们可以记录前一个与它颜色相同的笔last和后一个与它颜色相同的笔next,将last加入平衡树。
这样,询问L到R中不同的颜色的时候,查找L到R中多少支笔的last小于L,即为所求。
修改时要麻烦一些,首先删掉f[x]位置的last,之后将f[x]位置修改为颜色y,之后再将f[x]位置加入平衡树,大概意思还是看代码吧。
ps:build函数是将一个数加入平衡树,change函数是从平衡树中删除一个数
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define N 10010 #define M 1000010 #define inf 0x3f3f3f3f #define ls a[k].l #define rs a[k].r #define lowbit(x) x&-x using namespace std; struct ss { int last,next,v; }; ss f ; struct node { int l,r,v,w,size,rnd; }; node a[N*100]; int n,tot,tmp,size; int root ; int color[M]; void updata(int k) { a[k].size=a[ls].size+a[rs].size+a[k].w; } void lturn(int &k) { int t=a[k].r; a[k].r=a[t].l,a[t].l=k; a[t].size=a[k].size; updata(k); k=t; } void rturn(int &k) { int t=a[k].l; a[k].l=a[t].r,a[t].r=k; a[t].size=a[k].size; updata(k); k=t; } void insert(int &k,int x) { if(!k) { k=++size; a[k].v=x,a[k].w=a[k].size=1,a[k].rnd=rand(); return ; } a[k].size++; if(x==a[k].v)a[k].w++; else if(x>a[k].v) { insert(a[k].r,x); if(a[rs].rnd<a[k].rnd)lturn(k); }else { insert(a[k].l,x); if(a[ls].rnd<a[k].rnd)rturn(k); } } void del(int &k,int x) { if(a[k].v==x) { if(a[k].w>1)a[k].w--,a[k].size--; else if(a[k].l*a[k].r==0)k=a[k].l+a[k].r; else if(a[ls].rnd<a[rs].rnd)rturn(k),del(k,x); else lturn(k),del(k,x); } else if(x>a[k].v)del(a[k].r,x),a[k].size--; else del(a[k].l,x),a[k].size--; } int query(int k,int x) { if(!k)return 0; if(x<=a[k].v)return query(a[k].l,x); else return a[k].w+a[ls].size+query(a[k].r,x); } void build(int x,int c) { for(int i=x;i<=n;i+=lowbit(i)) insert(root[i],c); } void change(int x,int c) { for(int i=x;i<=n;i+=lowbit(i)) del(root[i],c); } int ask(int x,int c) { int ans=0; if(!x)return 0; for(int i=x;i>0;i-=lowbit(i)) ans+=query(root[i],c); return ans; } int main() { cin>>n>>tot; for(int i=1;i<=n;i++) { int x; scanf("%d",&x); f[i].last=color[x],f[i].v=x; f[color[x]].next=i,color[x]=i,f[i].next=inf; build(i,f[i].last); } for(int i=1;i<=tot;i++) { char s[10]; int x,y; scanf("%s%d%d",s,&x,&y); if(s[0]=='Q')printf("%d\n",ask(y,x)-ask(x-1,x)); else{ change(x,f[x].last); change(f[x].next,x); build(f[x].next,f[x].last); if(f[x].last!=0)f[f[x].last].next=f[x].next; if(f[x].next!=inf)f[f[x].next].last=f[x].last; if(f[x].next==inf)color[f[x].v]=f[x].last; f[x].v=y,f[x].last=color[y],f[x].next=0; while(f[x].last>x) { f[x].next=f[x].last; f[x].last=f[f[x].last].last; } if(f[x].next==0)f[x].next=inf; if(f[x].last!=0)f[f[x].last].next=x; if(f[x].next!=inf)f[f[x].next].last=x; if(f[x].next==inf)color[y]=x; build(x,f[x].last); build(f[x].next,x); change(f[x].next,f[x].last); } } return 0; }
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例