Multi-University 2015 #7 D(hdu 5372 Segment Game)
2016-06-26 14:50
351 查看
题目链接
插入的第x条线段长度为x。
在每次插入操作之前,先求出这个线段可以覆盖多少的完整的线段
于是拼死调出一棵线段树套平衡树,最值得担心的内存没炸,反而TLE了。
果断弃坑。
这套多校为什么总是不说数据的组数,太坑了
结果发现,我忘掉了最早发现,也是最重要的性质:线段是从小到大插入的。
由于线段是从小到大插入的,所以R[i]>R[x]的线段,都有L[i]>=L[x],所以答案就是L[i]>=L[x]的个数减去R[i]>L[x]的个数。
这个可以用两个BIT维护一下。
由于我的BIT是前缀和,而不是后缀和,所以
ans=(tot−cntL[i]>=L[x])−(tot−cntR[i]>R[x])=−cntL[i]>=L[x]+cntR[i]>R[x]
于是就好了。
题目大意
有两种操作,一是把线段插到[x,x+len]中,二是把第x条插入的线段删掉。插入的第x条线段长度为x。
在每次插入操作之前,先求出这个线段可以覆盖多少的完整的线段
题解
也不知道怎么的,就在十几分钟的努力思考之后,我居然得到了用树套树这一结论。于是拼死调出一棵线段树套平衡树,最值得担心的内存没炸,反而TLE了。
果断弃坑。
这套多校为什么总是不说数据的组数,太坑了
结果发现,我忘掉了最早发现,也是最重要的性质:线段是从小到大插入的。
由于线段是从小到大插入的,所以R[i]>R[x]的线段,都有L[i]>=L[x],所以答案就是L[i]>=L[x]的个数减去R[i]>L[x]的个数。
这个可以用两个BIT维护一下。
由于我的BIT是前缀和,而不是后缀和,所以
ans=(tot−cntL[i]>=L[x])−(tot−cntR[i]>R[x])=−cntL[i]>=L[x]+cntR[i]>R[x]
于是就好了。
#include<ctime> #include<cstdio> #include<cctype> #include<cstdlib> #include<algorithm> using namespace std; #define lowbit(x) (x&-x) const int S=20; const int M=200005; const int SIZE=M*S*2; int N,tot; int sz,ch[SIZE][2],siz[SIZE],key[SIZE],val[SIZE],cnt[SIZE]; int L[M],R[M],Table[M<<1]; struct BIT{ int bit[M<<1]; void init(){ for(int i=0;i<=tot;i++) bit[i]=0; } void add(int x,int f){ if(!x) return; while(x<=tot){ bit[x]+=f; x+=lowbit(x); } } int sum(int x){ int res=0; while(x){ res+=bit[x]; x-=lowbit(x); } return res; } }bit[2]; int a[M],b[M]; inline void rd(int&res){ res=0;char c; while(c=getchar(),!isdigit(c)); do res=res*10+(c^48); while(c=getchar(),isdigit(c)); } void print(int x){ if(!x) return; print(x/10); putchar(x%10^48); } inline void sc(int x){ if(!x) putchar('0'); else print(x); putchar('\n'); } int id[M]; int main(){ int cas=0; while(scanf("%d",&N)!=EOF){ printf("Case #%d:\n",++cas); int len=1; tot=0; sz=0; for(int i=0;i<N;i++){ rd(a[i]); scanf("%d",&b[i]); if(!a[i]){ Table[tot++]=b[i]; Table[tot++]=b[i]+len; len++; } } sort(Table,Table+tot); tot=unique(Table,Table+tot)-Table; len=1; for(int i=0;i<N;i++){ if(!a[i]){ L[i]=lower_bound(Table,Table+tot,b[i])-Table+1; R[i]=lower_bound(Table,Table+tot,b[i]+len)-Table+1; id[len]=i; len++; } } bit[0].init(); bit[1].init(); for(int i=0;i<N;i++){ if(!a[i]){ sc(-bit[0].sum(L[i]-1)+bit[1].sum(R[i])); bit[0].add(L[i],1); bit[1].add(R[i],1); }else{ bit[0].add(L[id[b[i]]],-1); bit[1].add(R[id[b[i]]],-1); } } } return 0; }
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- 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)