zoukankan      html  css  js  c++  java
  • HDU 4866 Shooting (主席树)

    题目链接  HDU 4866

    题意  给定$n$条线段。每条线段平行$x$轴,离x轴的距离为$D$,覆盖的坐标范围为$[L, R]$。

        现在有$m$次射击行动,每一次的射击行动可以描述为在横坐标$x$处找到离$x$轴最近的$k$条线段,

        并计算这$k$个目标距离$x$轴的总和。强制在线。

     

    对线段到$x$轴的距离离散化。 以横坐标为下标建立主席树。

    应用差分思想,对于每条线段,在$L$处标记$+1$,在$R+1$处标记$-1$,

    查询的时候在横坐标$x$处则查找横坐标$x$对应的主席树即可。

    主席树维护两个东西:

    $s[]$表示当前维护的区间范围内的权值和。

    $t[]$表示当前维护的区间范围内的权值个数。

    对于那点右端点很坐标小于$x$的线段,在之前的两次插入操作中正负抵消。

    于是就保证了查询到的线段横坐标范围覆盖了当前的$x$。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    const int M = 4e6 + 10;
    const int N = 2e5 + 10;
    
    struct node{
    	int pos, val, num;
    	friend bool operator < (const node &a, const node &b){
    		return a.pos == b.pos ? (a.val == b.val ? a.num < b.num : a.val < b.val) : (a.pos < b.pos);
    	}
    } c[M], nd;
    
    int ls[M], rs[M], tree[N], val[N], t[M], tot;
    int cnt, now, k, x, m, n, et, p;
    LL  s[M], pre, ans;
    
    void ins(int l, int r, int vl, int fl, int pre, int &x){
    	x = ++tot;
    	ls[x] = ls[pre];
    	rs[x] = rs[pre];
    
    	s[x] = s[pre] + fl * val[vl];
    	t[x] = t[pre] + fl;
    
    	if (l == r) return;
    
    	int mid = (l + r) >> 1;
    	if (vl <= mid) ins(l, mid, vl, fl, ls[pre], ls[x]);
    	else ins(mid + 1, r, vl, fl, rs[pre], rs[x]);
    }
    
    LL query(int id, int l, int r, int k){
    	if (l == r) return 1ll * k * val[l];
    
    	int mid = (l + r) >> 1;
    
    	if (t[ls[id]] > k) return query(ls[id], l, mid, k);
    	else if (t[ls[id]] == k) return s[ls[id]];
    	else return s[ls[id]] + query(rs[id], mid + 1, r, k - t[ls[id]]);
    }
    
    int main(){
    
    	while (~scanf("%d%d%d%d", &n, &m, &x, &p)){
    		et = 0;
    		rep(i, 1, n){
    			int l, r, d;
    			scanf("%d%d%d", &l, &r, &d);
    			val[i] = d;
    			++et;
    			c[et].pos = l;
    			c[et].val = d;
    			c[et].num = 1;
    			++et;
    			c[et].pos = r + 1;
    			c[et].val = d;
    			c[et].num = -1;
    		}
    
    		sort(val + 1, val + n + 1);
    		cnt = unique(val + 1, val + n + 1) - val - 1;
    
    		now = 0;
    
    		rep(i, 1, n << 1) c[i].val = lower_bound(val + 1, val + cnt + 1, c[i].val) - val;
    		sort(c + 1, c + 2 * n + 1);
    		tree[0] = ls[0] = rs[0] = s[0] = t[0] = tot = 0;
    
    		pre = 1;
    		now = 0;
    
    		rep(i, 1, 2 * n) ins(1, cnt, c[i].val, c[i].num, tree[i - 1], tree[i]);
    		rep(i, 1, m){
    			LL pos, a, b, cc;
    			scanf("%lld%lld%lld%lld", &pos, &a, &b, &cc);
    			k = (a * pre + b) % cc;
    
    			nd.pos = pos;
    			nd.val = 1e9;
    
    			int y = upper_bound(c + 1, c + 2 * n + 1, nd) - c - 1;
    			ans = query(tree[y], 1, cnt, k);
    
    			if (pre > p) ans *= 2;
    			pre = ans;
    
    			printf("%lld
    ", ans);
    		}
    
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    file is universal (3 slices) but does not contain a(n) armv7s slice error for static libraries on iOS
    WebImageButton does not change images after being enabled in Javascript
    ajax OPTION
    编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
    获取海洋天气预报
    C#线程系列教程(1):BeginInvoke和EndInvoke方法
    js控制只能输入数字和小数点
    Response.AddHeader(,)
    ManualResetEvent的理解
    Convert.ToInt32、int.Parse(Int32.Parse)、int.TryParse、(int) 区别
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8387690.html
Copyright © 2011-2022 走看看