HDU 4325 离散化 + 线段树
来源:互联网 发布:怎么查找淘宝评论过的 编辑:程序博客网 时间:2024/04/28 19:25
题意:
给出n个区间,【s,t】,区间,代表这个时间段有一朵花。
m个询问,每次询问一个时间点,输出该时间的花的数量。
思路:n <= 10W, m <= 10W 。
直接离散化之后然后线段树成段更新,输出点的值即可。
#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cmath>#include <cstring>#include <queue>#include <set>#include <vector>#include <stack>#include <map>#include <iomanip>#define PI acos(-1.0)#define Max 2005#define inf 2000000000#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)using namespace std;struct kdq{ int l,r; long long num , add;} tree[1111111];int n , m , t ;long long ans;void build_tree(int l,int r,int u){ tree[u].l=l,tree[u].r=r; tree[u].add=0; if(l==r) { tree[u].num = 0 ; return ; } int mid=(l+r)/2; build_tree(l,mid,u<<1); build_tree(mid+1,r,(u<<1)+1); tree[u].num=tree[u<<1].num + tree[(u<<1)+1].num;}void query(int left,int right,int u){ if(left>tree[u].r||right<tree[u].l) { return ; } if(left<=tree[u].l&&right>=tree[u].r) { ans+=tree[u].num; return ; } if(tree[u].add) { tree[u<<1].num += (tree[u<<1].r-tree[u<<1].l+1)*tree[u].add; tree[u<<1].add += tree[u].add; tree[(u<<1)+1].num += (tree[(u<<1)+1].r-tree[(u<<1)+1].l+1)*tree[u].add; tree[(u<<1)+1].add += tree[u].add; tree[u].add = 0; } query(left,right,u<<1); query(left,right,(u<<1)+1); tree[u].num=tree[u<<1].num+tree[(u<<1)+1].num;}void updata(int left,int right,int u,int k){ if(left>tree[u].r||right<tree[u].l) { return ; } if(left<=tree[u].l&&right>=tree[u].r) { tree[u].num+=(tree[u].r-tree[u].l+1)*k; tree[u].add+=k; return ; } if(tree[u].add) { tree[u<<1].num += (tree[u<<1].r-tree[u<<1].l+1)*tree[u].add; tree[u<<1].add += tree[u].add; tree[(u<<1)+1].num += (tree[(u<<1)+1].r-tree[(u<<1)+1].l+1)*tree[u].add; tree[(u<<1)+1].add += tree[u].add; tree[u].add = 0; } updata(left,right,u<<1,k); updata(left,right,(u<<1)+1,k); tree[u].num=tree[u<<1].num+tree[(u<<1)+1].num;}struct road{ int x ,y ;}a[100005] ;int b[1000005] ;int c[1000005] ;int main(){#ifndef ONLINE_JUDGE freopen("acm.txt", "r", stdin);#endif cin >> t ; int ca = 0 ; while( t -- ) { cin >> n >> m ; int dnum = 0 ; for (int i = 0 ;i < n ;i ++ ) { scanf("%d%d",&a[i].x ,&a[i].y) ; b[dnum ++ ] = a[i].x ; b[dnum ++ ] = a[i].y ; } for (int i = 0 ;i < m ;i ++ ) { scanf("%d",&c[i]) ; b[dnum ++ ] = c[i] ; } sort(b, b + dnum ) ; int nn = unique(b,b + dnum) - b ; build_tree(1,nn,1) ; printf("Case #%d:\n",++ca) ; for (int i = 0 ;i < n ;i ++ ) { int ss = lower_bound(b,b + nn ,a[i].x) - b + 1 ; int tt = lower_bound(b, b + nn ,a[i].y) - b + 1 ; updata(ss, tt,1,1) ; } for (int i = 0 ;i < m ;i ++ ) { ans = 0 ; int dd = lower_bound(b, b + nn ,c[i]) - b + 1 ; query(dd,dd,1) ; printf("%lld\n",ans) ; } } return 0;}
显然用树状数组区间更新单点查询更快,更好写
int n , m ,nn ,D[N] ,X[N] , Y[N] ,Q[N] ,c[N] ;int lowbit(int x){return x & (-x) ;}void update(int x , int y){ for (int i = x ; i >= 1 ; i -= lowbit(i))c[i] += y ;}int query(int x){ int ans = 0 ; for (int i = x ; i <= nn ; i += lowbit(i))ans += c[i] ; return ans ;}void solve(){ mem(c , 0) ; cin >> n >> m ;int num = 0 ; for (int i = 0 ; i < n ; i ++ ){ RD(X[i]) ; RD(Y[i]) ;D[num ++ ] = X[i] ; D[num ++ ] = Y[i] ; } for (int i = 0 ; i < m ; i ++ ){ RD(Q[i]) ; D[num ++ ] = Q[i] ; } sort(D , D + num) ; int k = unique(D , D + num ) - D ; nn = k ; for (int i = 0 ; i < n ; i ++ ){ int x = lower_bound(D, D + k , X[i]) - D + 1 ; int y = lower_bound(D ,D + k , Y[i]) - D + 1 ; update(x - 1 , -1) ; update(y , 1) ; } for (int i = 0 ; i < m ; i ++ ){ printf("%d\n",query(lower_bound(D, D + k , Q[i]) - D + 1)) ; }}int main() { int _ ;int ca = 0 ; cin >> _ ; while(_ -- )printf("Case #%d:\n",++ ca) ,solve() ; return 0;}
- hdu(4325)线段树+离散化+lazy
- HDU 4325 离散化 + 线段树
- hdu 4325 Flowers(线段树+离散化)
- hdu 4325 Flowers(离散化+线段树)
- HDU 4325 Flowers (线段树+离散化)
- HDU 4325&& nyoj 600 Flowers【线段树+坐标离散化】
- HDU 4325 Flowers(线段树+离散化)
- HDU 4828 Coder(线段树 + 离散化)
- HDU 4288 线段树+离散化
- hdu 2528(离散化线段树)
- hdu 4288 线段树+离线+离散化
- HDU 4288 Coder 离散化+线段树
- hdu 4288 线段树+离散化
- HDU 3607 线段树+离散化+DP
- hdu 1255(线段树+离散化)
- hdu 5877 线段树+离散化+DFS
- HDU 3333 线段树+离散化
- hdu 4325 Flowers 线段树+离散化(要学会离散化的方法)
- C++运算符重载
- hdoj_2586How far away ? && poj_1986Distance Queries
- 编程多年的一些疑问
- Socket编程 简易测试socket UDP
- 多线程删除注册的事件
- HDU 4325 离散化 + 线段树
- 题目1075:斐波那契数列
- ubuntu12.04建立交叉编译环境,bin/.arm-none-linux-gnueabi-gcc: not found
- 反射
- Android中消息系统模型和Handler Looper
- c#文件读写相关类介绍
- Android基础 - No Launcher activity found!
- ListView内控件与listview抢夺焦点
- 在webservice中传输实体对象