CodeForces 610D Vika and Segments

题目链接:

http://codeforces.com/problemset/problem/610/D

------------------------------------------------------------------------------------

虽然说这题是线段并 但是如果会写矩形面积并的话就直接写矩形并不用考虑那么多了

不过这里额外说明下 写矩形面积并的线段树的时候

要注意到某一段 $ -1 $一定是在这一段$ +1 $之后才会出现的操作

因此标记就是这一段被“完全”覆盖的次数 并且部分修改时无需进行标记下放

这题作为矩形面积并的第一道题也是很适合的

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 1e5 + 10;
 7 struct rec
 8 {
 9     int xa, ya, xb, yb;
10 }a[N];
11 struct line
12 {
13     int x, ya, yb, num;
14 }b[N << 1];
15 int hash[N << 1];
16 int sum[N << 3], flag[N << 3];
17 int n;
18 long long ans = 0;
19 bool cmp (const line &aa, const line &bb)
20 {
21     return aa.x < bb.x;
22 }
23 void pushup(int x, int tl, int tr)
24 {
25     if(flag[x])
26         sum[x] = hash[tr + 1] - hash[tl];
27     else if(tl != tr)
28         sum[x] = sum[x << 1] + sum[x << 1 | 1];
29     else
30         sum[x] = 0;
31     return;
32 }
33 void update(int x, int L, int R, int tl, int tr, int num)
34 {
35     if(L <= tl && R >= tr)
36     {
37         flag[x] += num;
38         pushup(x, tl, tr);
39         return;
40     }
41     int mid = (tl + tr) >> 1;
42     if(L <= mid)
43         update(x << 1, L, R, tl, mid, num);
44     if(R > mid)
45         update(x << 1 | 1, L, R, mid + 1, tr, num);
46     pushup(x, tl, tr);
47 }
48 int main()
49 {
50     scanf("%d", &n);
51     for(int i = 1; i <= n; ++i)
52     {
53         scanf("%d%d%d%d", &a[i].xa, &a[i].ya, &a[i].xb, &a[i].yb);
54         if(a[i].xa > a[i].xb)
55             swap(a[i].xa, a[i].xb);
56         if(a[i].ya > a[i]. yb)
57             swap(a[i].ya, a[i].yb);
58         ++a[i].xb;
59         ++a[i].yb;
60         hash[i * 2 - 1] = a[i].ya;
61         hash[i * 2] = a[i].yb;
62         b[i * 2 - 1].x = a[i].xa;
63         b[i * 2 - 1].num = 1;
64         b[i * 2].x = a[i].xb;
65         b[i * 2].num = -1;
66         b[i * 2].ya = b[i * 2 - 1].ya = a[i].ya;
67         b[i * 2].yb = b[i * 2 - 1].yb = a[i].yb;
68     }
69     sort(hash + 1, hash + 1 + n * 2);
70     sort(b + 1, b + 1 + n * 2, cmp);
71     b[0].x = b[1].x;
72     for(int i = 1; i <= n * 2; ++i)
73     {
74         int L, R;
75         L = lower_bound(hash + 1, hash + 1 + n * 2, b[i].ya) - hash;
76         R = lower_bound(hash + 1, hash + 1 + n * 2, b[i].yb) - hash - 1;
77         ans += (long long) (b[i].x - b[i - 1].x) * sum[1];
78         update(1, L, R, 1, n * 2 - 1, b[i].num);
79     }
80     printf("%lld\n", ans);
81     return 0;
82 }
时间: 2024-10-14 12:49:08

CodeForces 610D Vika and Segments的相关文章

Codeforces 610D Vika and Segments 线段树+离散化+扫描线

可以转变成上一题(hdu1542)的形式,把每条线段变成宽为1的矩形,求矩形面积并 要注意的就是转化为右下角的点需要x+1,y-1,画一条线就能看出来了 #include<bits/stdc++.h> #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker,

610D - Vika and Segments(线段树+扫描线+离散化)

扫描线:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html 看图,图中的数字是横坐标离散后对应的下标,计算时左端点不变,右端点加1,所以总的更新的区间是l到r-1. 也可以理解为1代表的是(1到2这一段),2代表的是(2到3这一段),3代表的是(3到4这一段)... 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #de

Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并

D. Vika and Segments Vika has an infinite sheet of squared paper. Initially all squares are white. She introduced a two-dimensional coordinate system on this sheet and drew n black horizontal and vertical segments parallel to the coordinate axes. All

Codeforces 430A Points and Segments (easy)

题意:让你染色点,要求在给出的区间内|红色个数-蓝色个数|<=1 思路:排序后依次交替染色就能达到效果 #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <vector> using namespace std; const int MAXN = 110; int arr[MAXN]; int n,m,x,y; int

Vika and Segments - CF610D

Vika has an infinite sheet of squared paper. Initially all squares are white. She introduced a two-dimensional coordinate system on this sheet and drew n black horizontal and vertical segments parallel to the coordinate axes. All segments have width

CodeForces A. Points in Segments

http://codeforces.com/contest/1015/problem/A You are given a set of nn segments on the axis OxOx, each segment has integer endpoints between 11 and mm inclusive. Segments may intersect, overlap or even coincide with each other. Each segment is charac

Codeforces 1108E2 Array and Segments (Hard version) 差分, 暴力

Codeforces 1108E2 E2. Array and Segments (Hard version) Description: The only difference between easy and hard versions is a number of elements in the array. You are given an array \(a\) consisting of \(n\) integers. The value of the \(i\)-th element

Codeforces 620F Xors on Segments(暴力+DP)

题目链接 Xors on Segments 预处理出x[i] = 1 ^ 2 ^ 3 ^ -- ^ i; (话说这题O(N^2居然能过)) 先对询问离线. 然后dp[i]表示以a[i]为开头的所有连续序列中最大答案. 然后依次处理到a[j]的时候如果以j为右端点的询问的左端点小于等于i则更新. 复杂度O(N^2) 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for (int i(a);

Codeforces 620F Xors on Segments 回滚莫队 + 字典树 || 离心询问分治 + 可持久化字典树

Xors on Segments 转换一下变成询问区间选两个数异或的最大值, 要注意的是一个数作为左端点要-1, 所以在回滚莫队的时候用两棵字典树维护. 这个题居然n ^ 2 也能过...  其实用分治 + 可持久化字典树可以做到n * log(n) * log(n), 懒得写了... #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #defin