Madiyar

Petrozavodsk 2012 day 6 I

Sep 2nd, 2012
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <cmath>
  7. #include <vector>
  8. #include <map>
  9. #include <set>
  10. #include <ctime>
  11. #include <cassert>
  12. #include <queue>
  13.  
  14. using namespace std;
  15.  
  16. #define f first
  17. #define s second
  18. #define mp make_pair
  19. #define pb push_back
  20. #define forit(it,con) for (typeof(con.begin()) it = con.begin(); it != con.end(); ++it)
  21. #define f0(a) memset(a, 0, sizeof(a))
  22. #define all(v) v.begin(), v.end()
  23. #define pii pair<int,int>
  24. #define ll long long
  25.  
  26. #ifdef WIN32
  27.     #define I64 "%I64d"
  28. #else
  29.     #define I64 "%lld"
  30. #endif
  31. const int maxn = 200000;
  32.  
  33. const int inf = (int)1e9 * 2;
  34.  
  35. struct Tree {
  36.     Tree *L, *R;
  37.     int val;
  38.     Tree(int _val = inf) {
  39.         L = R = 0;
  40.         val = _val;
  41.     }
  42.  
  43.     Tree(Tree *l, Tree *r) {
  44.         L = l; R = r;
  45.         val = inf;
  46.         if (L) val = min(val, L -> val);
  47.         if (R) val = min(val, R -> val);
  48.     }
  49. } *root;
  50. int n;
  51.  
  52. pii a[maxn];
  53. pii A[4][maxn];
  54. int Y[4][maxn];
  55. int Yn[4];
  56. Tree *ver[4][maxn];
  57.  
  58.  
  59. inline Tree * Build( int l, int r) {
  60.     if (l > r) return 0;
  61.     if (l == r) return new Tree();
  62.     int mid = (l + r) >> 1;
  63.     return new Tree(Build(l, mid), Build(mid + 1, r));
  64. }
  65.  
  66. inline Tree * update(Tree *v, int pos, int val, int l, int r) {
  67.     if (l > r) return 0;
  68.     if (l == r) return new Tree(min(val, v->val));     
  69.  
  70.     int mid = (l + r) >> 1;
  71.  
  72.     if (pos <= mid)
  73.         return new Tree(update(v->L, pos, val, l, mid), v->R);
  74.     else
  75.         return  new Tree(v->L, update(v->R, pos, val, mid + 1, r));
  76.    
  77. }
  78.  
  79. inline void Create(int cur) {
  80.  
  81.     for (int i = 0; i < n; ++i) {
  82.         A[cur][i] = a[i];
  83.         Y[cur][Yn[cur]++] = a[i].s;
  84.     }
  85.  
  86.  
  87.     sort(Y[cur], Y[cur] + Yn[cur]);
  88.     Yn[cur] = unique(Y[cur], Y[cur] + Yn[cur]) - Y[cur];
  89.  
  90.     sort(A[cur], A[cur] + n);  
  91.    
  92.     root = Build(1, Yn[cur]);
  93.     cerr << clock() / (double)CLOCKS_PER_SEC << " running kirdi " << endl;
  94.  
  95.     for (int i = n - 1; i >= 0; --i) {
  96.         int pos = lower_bound(Y[cur], Y[cur] + Yn[cur], A[cur][i].s) - Y[cur] + 1;
  97.         root = update(root, pos, A[cur][i].f + A[cur][i].s, 1, Yn[cur]);
  98.         ver[cur][i] = root;
  99.     }    
  100.     cerr << clock() / (double)CLOCKS_PER_SEC << " running wykty " << endl;
  101.  
  102.  
  103. }
  104.  
  105. inline int findMin(Tree *v, int l, int r, int sl, int sr) {
  106.     if (l > r || sl > sr)  return inf;
  107.     if (min(sr, r) - max(sl, l) < 0) return inf;
  108.  
  109.     if (l <= sl && sr <= r) return v -> val;
  110.  
  111.     int mid = (sl + sr) >> 1;
  112.  
  113.     return min(findMin(v -> L, l, r, sl, mid), findMin(v -> R, l, r, mid + 1, sr));
  114. }
  115.  
  116. inline int Dist(int cur, int x, int y) {
  117.     int px = lower_bound(A[cur], A[cur] + n, mp(x, -inf)) - A[cur];
  118.    
  119.     int py = lower_bound(Y[cur], Y[cur] + Yn[cur], y) - Y[cur];
  120.  
  121.     if (px == n || py == Yn[cur]) return inf;
  122.        
  123.     return findMin(ver[cur][px], py + 1, Yn[cur], 1, Yn[cur]) - x - y;  
  124. }
  125.  
  126. int main() {
  127.     #ifdef LOCAL
  128.         freopen("in","r",stdin);
  129.         freopen("out","w",stdout);
  130.     #endif  
  131.     int A, B, C, D, E, F, M, q;
  132.     scanf("%d%d", &n, &q);
  133.     scanf("%d", &M);
  134.     scanf("%d%d%d", &A, &B, &C);
  135.     scanf("%d%d%d", &D, &E, &F);
  136.  
  137.     for (int i = 0; i < n; ++i) {
  138.         int x, y;
  139.         scanf("%d%d", &x, &y);
  140.         a[i] = mp(x - y, x + y);
  141.     }
  142.  
  143.  
  144.     for (int i = 0; i < 2; ++i) {
  145.        
  146.         for (int j = 0; j < 2; ++j) {
  147.             Create(i * 2 + j);
  148.            
  149.             for (int k = 0; k < n; ++k)
  150.                 a[k].s *= -1;
  151.         }
  152.  
  153.         for (int k = 0; k < n; ++k)
  154.             a[k].f *= -1;
  155.  
  156.     }
  157.    
  158.     int x, y;
  159.     scanf("%d%d", &x, &y);  
  160.     long long anssum = 0;
  161.     for (int i = 0; i < q; ++i) {
  162.  
  163.         int nx = x - y, ny = x + y;
  164.  
  165.         int ans = Dist(0, nx, ny);
  166.         ans = min(ans, Dist(1, nx, -ny));
  167.         ans = min(ans, Dist(2, -nx, ny));
  168.         ans = min(ans, Dist(3, -nx, -ny));
  169.         ans >>= 1;
  170.        
  171.         x = (abs(1ll * A * x + 1ll * B * ans + C) % (2 * M + 1)) - M;
  172.         y = (abs(1ll * D * y + 1ll * E * ans + F) % (2 * M + 1)) - M;
  173.         anssum += ans;
  174.     }
  175.     cout << anssum << endl;
  176.     return 0;
  177. }
Advertisement
Add Comment
Please, Sign In to add comment