zoukankan      html  css  js  c++  java
  • ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)

    ZOJ 3597

    题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你被允许选择一个连续的Q个靶子,使得这P把枪所打到的靶子的数目最多,问打到的靶子数目的期望值是多少。

    这题通过简单的转化就可以转换成为另一个模型:

    如果第a把枪可以打到第b个靶子,那么将其视为二位平面上的一个点(b, a), 问题转化为一个Q * P的矩形最多可以覆盖多少个点。只是有一点需要注意的就是同一把枪只能打到一个靶子,所以在a相等的情况下最多只能覆盖一个b。

    至于如何求矩形覆盖点的个数,我这也是第一次写,所以查阅了有关资料。

    方法是将矩形的右界作为参考点,找出参考点在哪一个区间(线段)内矩形都可以覆盖到这个点,这样每一个点就对应y相等的一段线段,原题就转化成为了高度y小于P的区间内某一个位置x上的覆盖次数的最大值,可以用线段树的离线操作(扫描线)来完成。

      1 #include <map>
      2 #include <set>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <vector>
      8 #include <cstdio>
      9 #include <cctype>
     10 #include <cstring>
     11 #include <cstdlib>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 #define INF 0x3f3f3f3f
     16 #define inf (-((LL)1<<40))
     17 #define lson k<<1, L, (L + R)>>1
     18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
     19 #define mem0(a) memset(a,0,sizeof(a))
     20 #define mem1(a) memset(a,-1,sizeof(a))
     21 #define mem(a, b) memset(a, b, sizeof(a))
     22 #define FIN freopen("in.txt", "r", stdin)
     23 #define FOUT freopen("out.txt", "w", stdout)
     24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
     25 
     26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
     27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
     28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
     29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
     30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
     31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
     32 
     33 //typedef __int64 LL;
     34 typedef long long LL;
     35 const int MAXN = 51000;
     36 const int MAXM = 110000;
     37 const double eps = 1e-4;
     38 //LL MOD = 987654321;
     39 
     40 #define OK(i) (i > 0 && p[i - 1].y == p[i].y && p[i].x <= p[i - 1].x + Q - 1)
     41 
     42 int T, N, M, P, Q, K;
     43 struct Point {
     44     int x, y;
     45     bool operator < (const Point &A) const {
     46         return y == A.y ? x < A.x : y < A.y;
     47     }
     48 }p[MAXM];
     49 
     50 struct SegTree {
     51     LL ma[MAXN<<2], add[MAXN<<2];
     52 
     53     void build(int k, int L, int R) {
     54         ma[k] = add[k] = 0;
     55         if(L == R)  return ;
     56         build(lson); build(rson);
     57     }
     58 
     59     void pushDown(int k) {
     60         ma[k<<1] += add[k];   add[k<<1] += add[k];
     61         ma[k<<1|1] += add[k]; add[k<<1|1] += add[k];
     62         add[k] = 0;
     63     }
     64 
     65     void update(int k, int L, int R, int l, int r, int val) {
     66         if(R < l || L > r) return ;
     67         if(l <= L && R <= r) { ma[k] += val; add[k] += val; return ; }
     68         pushDown(k);
     69         update(lson, l, r, val);
     70         update(rson, l, r, val);
     71         ma[k] = max(ma[k<<1], ma[k<<1|1]);
     72     }
     73 
     74     LL query(int k, int L, int R, int l, int r) {
     75         if(R < l || L > r) return 0;
     76         if(l <= L && R <= r) return ma[k];
     77         pushDown(k);
     78         return max(query(lson, l, r), query(rson, l, r));
     79     }
     80 
     81 }segTree;
     82 
     83 int main()
     84 {
     85     //FIN;
     86     while(~scanf("%d", &T)) while(T--)
     87     {
     88         scanf("%d %d %d %d %d", &N, &M, &P, &Q, &K);
     89         rep (i, 0, K - 1) scanf("%d %d", &p[i].y, &p[i].x);
     90         sort(p, p + K);
     91 
     92         segTree.build(1, 1, M);
     93         LL ans = 0, fr = 0, re = 0;
     94         rep (i, P, N) {
     95             while(fr < K && p[fr].y <= i) {
     96                 int st = OK(fr) ? p[fr-1].x + Q : p[fr].x;
     97                 int ed = min(p[fr].x + Q - 1, M);
     98                 segTree.update(1, 1, M, st, ed, 1);
     99                 fr ++;
    100             }
    101             while(i - p[re].y >= P) {
    102                 int st = OK(re) ? p[re-1].x + Q : p[re].x;
    103                 int ed = min(p[re].x + Q - 1, M);
    104                 segTree.update(1, 1, M, st, ed, -1);
    105                 re ++;
    106             }
    107             ans += segTree.query(1, 1, M, 1, M);
    108         }
    109         printf("%.2lf
    ", (double)ans / (N - P + 1));
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    论文:CNN-based RGB-D Salient Object Detection: Learn, Select and Fuse
    APP网站小程序微信登录同步:需要微信公众号、小程序、开放平台打通用户体系(不同主体也行)
    jackson fastjson 对比 小计
    Speeding up DQN on PyTorch: how to solve Pong in 30 minutes
    Finite Meta-Dynamic Neurons in Spiking Neural Networks for Spatio-temporal Learning
    Spatio-Temporal Backpropagation for Training High-performance Spiking Neural Networks
    第四次课程设计实验报告
    第三次课程设计实验报告
    第二次课程设计实验报告
    第一次课程设计实验报告
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/4493091.html
Copyright © 2011-2022 走看看