HDU 1166 敌兵布阵
单调更新区间查询和
#include
HDU 1754 I Hate It
单点更新区间查询最值
#include
POJ 3468 A Simple Problem with Integers
区间更新区间求和。
这里就要涉及到懒操作。注意的是lazy被更新的区间一定是当前的区间和已经更新完
#include
POJ 2528 Mayor's posters
区间更新为一个值。然后统计有哪些数出现过
注意需要离散化,且不能随便离散化。
线段树是点操作。这里对长度为1的段进行操作。也就是将一个长度为1的段视作一个点,举个例子
区间为 1-10,1--4,5 -- 10
区间为 1--10,1--4,6-10;
一般的离散化是变成了这样 1离散为1,4离散为2,5离散为3,10离散为4
区间都变成了1-4,1--2,3 -- 4;
显然上面2中答案是不一样的。随便离散是WA的。第一个答案是2,第二个答案是3
那么如何改,方案是如果两个相邻的点差值大于1,那么中间就插入一个点。
那么按照这种离散上面变成了有6个点1,3,4,5,9,10,离散成了1-6,1-3,4-6 答案为2
和第二组问题 变成这样几个点1 3 4 5 6 9 10 离散成了 1--7,1--3,5--7答案为3
代码
#include
hdu 1698 Just a Hook
记得题意是如果一个区间值全部相等,那么权就是这个区间的长度乘以这个值,最开始全都是1
用一个sta记录这个区间是不是所值都相等然后做
#include
ZOJ 1610 Count the Colors
只有一次查询。可以直接暴力出来修改后最后每个点的颜色。然后扫一遍
我第一次的做法不知道为何就是老WA。求好心人告知。
下面是参照别人A的代码
结构体的COL表示染了什么颜色
#include
下面是我自己WA的代码在查询中就更新出答案不知道那里有问题
#include
POJ 3264 Balanced Lineup
查询区间最大最小值。
#include
HDU 4027 Can you answer these queries?
每次操作把区间内所有值开跟好向下取整,最大的数最多开7次根到1,所以直接做区间长度等于区间和直接结束
#include
HDU 1540 Tunnel Warfare
维护左连续长,右连续长,最大连续长度
#include
HDU 3794 Assign the task
其实就一个树形转线性
别的随便做,代码里有排除爆炸手写的树形转线性存一下模版
#pragma comment(linker, "/STACK:102400000,102400000") #include
HDU 4578 Transformation
这题很吊看这里 http://www.cnblogs.com/Commence/p/4871352.html
HDU 4614 Vases and Flowers
如果某个点可以插花,那么这个点值为1,由于他就是从左往右一直插花,实际上就是二分+区间和的问题。
然后查询一个区间最左边的1和最右边的1
#include
HDU 4553 约会安排
一个优先级问题,优先女神,然后吊斯
女神的询问中先在吊死中找如果吊死中可以满足就同时更新吊死和女神的那个区间值详情看代码
#include
POJ 1177 Picture
线段树扫描线矩形周长并
#include
HDU 1542 Atlantis
线段树扫描线举行面积并
#include
HDU 1255 覆盖的面积
矩形被覆盖2次以上的面积并。这个你要理解下这类问题是怎么解决的
首先c只有的被完全区间的时候会更新,区间被覆盖一次的长度表示什么,并不是一定就只覆盖了一次,
详细的看看callen函数。
#include
HDU 3642 Get The Treasury
线段树扫面线三维体积并,要求三次的内容。由于Z的绝对值小于500,所以可以枚举z
然后化为2唯来做
如何计算callen 中的once,twice,more是关键,理解很关键
#include
离散处理题目。求区间内不同数字的和,和不同数字的个数
Uvalive 5970 An Average Game
离散右端点排序每次标记上一次出现的位置
#includeusing namespace std; const int MAXN = 100100; #define LL long long struct node { int l,r; int idx; friend bool operator < (const node &a,const node &b) { if (a.r == b.r) return a.l < b.l; return a.r < b.r; } }src[MAXN]; int N,Q; LL A[MAXN]; pair ans[MAXN ]; struct treenode { int l,r; int sum; }tree[MAXN * 4]; void build(int id,int l,int r) { tree[id].l = l; tree[id].r = r; tree[id].sum = 0; if (l >= r) return; int mid = (l + r) / 2; build(id * 2,l,mid); build(id * 2 + 1,mid + 1,r); } void update(int id,int pos,bool flag) { if (tree[id].l == pos && tree[id].r == pos) { if (flag) tree[id].sum = 0; else tree[id].sum = 1; return; } int mid = (tree[id].l + tree[id].r) / 2; if (pos <= mid) update(id * 2,pos,flag); else update(id * 2 + 1,pos,flag); tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum; } int query(int id,int l,int r) { if (tree[id].l >= l && tree[id].r <= r) { return tree[id].sum; } int mid = (tree[id].l + tree[id].r) / 2; if (r <= mid) return query(id * 2,l,r); else if (l > mid) return query(id * 2 + 1,l,r); else { return query(id * 2,l,mid) + query(id * 2 + 1,mid + 1,r); } } struct IntervalTree { LL sum[MAXN * 4]; void build(){memset(sum,0,sizeof(sum));} void update(int o,int l,int r,int pos,int val) { if(l == r) { sum[o] += val; return; } int mid = (l + r) >> 1; if(pos <= mid)update(o << 1,l,mid,pos,val); else update(o<< 1 | 1,mid + 1,r,pos,val); sum[o]=sum[o << 1]+sum[o << 1 |1]; } LL query(int o,int l,int r,int q1,int q2) { if(q1 <= l && r <= q2)return sum[o]; int mid=(l + r)>>1; LL ans=0; if(q1 <= mid)ans += query(o << 1,l,mid,q1,q2); if(q2 > mid)ans += query(o << 1 | 1,mid + 1,r,q1,q2); return ans; } }Tree; map<int,int>vis; int main() { int T,kase = 1; cin >> T; while (T--) { cin >> N; for (int i = 1 ; i <= N ; i++) cin >> A[i]; cin >> Q; for (int i = 1 ; i <= Q ; i++) { cin >> src[i].l >> src[i].r; if (src[i].l > src[i].r) swap(src[i].l,src[i].r); } for (int i = 1 ; i <= Q ; i++) src[i].idx = i; vis.clear(); sort(src + 1,src + 1 + Q); build(1,1,N); int curpos = 1; for (int i = 1 ; i <= Q ; i++) { while (curpos <= N && curpos <= src[i].r) { if (vis[A[curpos]]) update(1,vis[A[curpos]],true); update(1,curpos,false); vis[A[curpos]] = curpos; curpos++; } ans[src[i].idx].first = (LL)query(1,src[i].l,src[i].r); } Tree.build(); vis.clear(); int cur = 1; for(int i = 1 ; i <= Q ; i++) { for(; cur <= N && cur <= src[i].r ; cur++) { if(vis[A[cur]])Tree.update(1,1,N,vis[A[cur]],-A[cur]); Tree.update(1,1,N,cur,A[cur]); vis[A[cur]] = cur; } ans[src[i].idx].second = Tree.query(1,1,N,src[i].l,src[i].r); } // for (int i = 1 ; i <= Q ; i++) cout << ans[i].first << " " << ans[i].second << endl; printf("Case %d:\n",kase++); for (int i = 1 ; i <= Q ; i++) printf("%.6lf\n",(1.0 * ans[i].second) / (1.0 * ans[i].first)); } return 0; }