Skip to content

Commit 30554d1

Browse files
committed
cdq 分治
1 parent fa3f516 commit 30554d1

File tree

4 files changed

+300
-43
lines changed

4 files changed

+300
-43
lines changed

Luogu/ShengXuan/P3157(2).cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <cstdio>
2+
#include <algorithm>
3+
#include <ctype.h>
4+
const int bufSize = 1e6;
5+
inline char nc()
6+
{
7+
#ifdef DEBUG
8+
return getchar();
9+
#endif
10+
static char buf[bufSize], *p1 = buf, *p2 = buf;
11+
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, bufSize, stdin), p1 == p2) ? EOF : *p1++;
12+
}
13+
inline void read(char *s)
14+
{
15+
static char c;
16+
for (; !isalpha(c); c = nc());
17+
for (; isalpha(c); c = nc()) *s++ = c;
18+
*s = '\0';
19+
}
20+
template<typename T>
21+
inline T read(T &r)
22+
{
23+
static char c;
24+
static int flag;
25+
flag = 1, r = 0;
26+
for (c = nc(); !isdigit(c); c = nc()) if (c == '-') flag = -1;
27+
for (; isdigit(c); c = nc()) r = r * 10 + c - 48;
28+
return r *= flag;
29+
}
30+
const int maxn = 5e5 + 100;
31+
int n, m, a[maxn];
32+
struct node
33+
{
34+
int t, p, v, type;
35+
} A[maxn], B[maxn];
36+
int main()
37+
{
38+
read(n), read(m);
39+
for (int i = 1; i <= n; ++i) read(a[i]);
40+
41+
return 0;
42+
}

Luogu/ShengXuan/P3810(2).cpp

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,66 @@
1-
#include <cstdio>
21
#include <algorithm>
3-
template<typename T>
4-
void read(T &r)
2+
#include <cstdio>
3+
4+
template <typename T>
5+
void read(T& r)
56
{
6-
static char c;r=0;
7-
for(c=getchar();c>'9'||c<'0';c=getchar());
8-
for(;c>='0'&&c<='9';r=(r<<1)+(r<<3)+(c^48),c=getchar());
7+
static char c;
8+
r = 0;
9+
for (c = getchar(); c > '9' || c < '0'; c = getchar())
10+
;
11+
for (; c >= '0' && c <= '9'; r = (r << 1) + (r << 3) + (c ^ 48), c = getchar())
12+
;
913
}
1014
const int maxn = 2e5 + 100;
1115
struct node
1216
{
13-
int a,b,c,d,cnt,id;
14-
}A[maxn],B[maxn],C[maxn];
15-
int n,maxk,tot;
16-
bool cmp(const node &x,const node &y)
17+
int a, b, c, d, cnt, id;
18+
} A[maxn], B[maxn], C[maxn];
19+
int n, maxk, tot;
20+
bool cmp(const node& x, const node& y)
1721
{
18-
if(x.a != y.a) return x.a < y.a;
19-
if(x.b != y.b) return x.b < y.b;
22+
if (x.a != y.a) return x.a < y.a;
23+
if (x.b != y.b) return x.b < y.b;
2024
return x.c < y.c;
2125
}
2226
int ans[maxn];
2327

24-
void cdq2(int l,int r)
28+
void cdq2(int l, int r)
2529
{
26-
if(l == r) return;
30+
if (l == r) return;
2731
int mid = l + r >> 1;
28-
cdq2(l,mid),cdq2(mid + 1,r);
29-
int p = l,q = mid + 1,k = l,sum = 0;
30-
while(p <= mid && q <= r)
32+
cdq2(l, mid), cdq2(mid + 1, r);
33+
int p = l, q = mid + 1, k = l, sum = 0;
34+
while (p <= mid && q <= r)
3135
{
32-
if(B[p].c <= B[q].c)
36+
if (B[p].c <= B[q].c)
3337
{
3438
sum += B[p].d;
3539
C[k++] = B[p++];
3640
}
3741
else
3842
{
39-
if(!B[q].d) ans[B[q].id] += sum;
43+
if (!B[q].d) ans[B[q].id] += sum;
4044
C[k++] = B[q++];
4145
}
4246
}
43-
while(p <= mid) C[k++] = B[p++];
44-
while(q <= r)
47+
while (p <= mid) C[k++] = B[p++];
48+
while (q <= r)
4549
{
46-
if(!B[q].d) ans[B[q].id] += sum;
50+
if (!B[q].d) ans[B[q].id] += sum;
4751
C[k++] = B[q++];
4852
}
49-
for(int i = l;i<=r;++i) B[i] = C[i];
53+
for (int i = l; i <= r; ++i) B[i] = C[i];
5054
}
51-
void cdq(int l,int r)
55+
void cdq(int l, int r)
5256
{
53-
if(l == r) return;
57+
if (l == r) return;
5458
int mid = l + r >> 1;
55-
cdq(l,mid),cdq(mid + 1,r);
56-
int p = l,q = mid + 1,k = l;
57-
while(p <= mid && q <= r)
59+
cdq(l, mid), cdq(mid + 1, r);
60+
int p = l, q = mid + 1, k = l;
61+
while (p <= mid && q <= r)
5862
{
59-
if(A[p].b <= A[q].b)
63+
if (A[p].b <= A[q].b)
6064
{
6165
A[p].d = A[p].cnt;
6266
B[k++] = A[p++];
@@ -67,25 +71,26 @@ void cdq(int l,int r)
6771
B[k++] = A[q++];
6872
}
6973
}
70-
while(p <= mid) A[p].d = A[p].cnt,B[k++] = A[p++];
71-
while(q <= r) A[q].d = 0,B[k++] = A[q++];
72-
for(int i = l;i<=r;++i) A[i] = B[i];
73-
cdq2(l,r);
74+
while (p <= mid) A[p].d = A[p].cnt, B[k++] = A[p++];
75+
while (q <= r) A[q].d = 0, B[k++] = A[q++];
76+
for (int i = l; i <= r; ++i) A[i] = B[i];
77+
cdq2(l, r);
7478
}
7579
int d[maxn];
7680
int main()
7781
{
78-
read(n),read(maxk);
79-
for(int i = 1;i<=n;++i) read(B[i].a),read(B[i].b),read(B[i].c),B[i].cnt = 1,B[i].id = i;
80-
std::sort(B + 1,B + 1 + n,cmp);
81-
for(int i = 1;i<=n;++i)
82+
read(n), read(maxk);
83+
for (int i = 1; i <= n; ++i) read(B[i].a), read(B[i].b), read(B[i].c), B[i].cnt = 1, B[i].id = i;
84+
std::sort(B + 1, B + 1 + n, cmp);
85+
for (int i = 1; i <= n; ++i)
8286
{
83-
if(B[i].a == B[i+1].a && B[i].b == B[i+1].b && B[i].c == B[i+1].c)
84-
B[i+1].cnt += B[i].cnt;
85-
else A[++tot] = B[i];
87+
if (B[i].a == B[i + 1].a && B[i].b == B[i + 1].b && B[i].c == B[i + 1].c)
88+
B[i + 1].cnt += B[i].cnt;
89+
else
90+
A[++tot] = B[i];
8691
}
87-
cdq(1,tot);
88-
for(int i = 1;i<=tot;++i) d[ans[A[i].id] + A[i].cnt] += A[i].cnt;
89-
for(int i = 1;i<=n;++i) printf("%d\n",d[i]);
92+
cdq(1, tot);
93+
for (int i = 1; i <= tot; ++i) d[ans[A[i].id] + A[i].cnt] += A[i].cnt;
94+
for (int i = 1; i <= n; ++i) printf("%d\n", d[i]);
9095
return 0;
9196
}

templates/cdq.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include <algorithm>
2+
#include <cstdio>
3+
const int maxn = 1e5 + 100;
4+
namespace cdq
5+
{
6+
int n;
7+
struct node
8+
{
9+
int a, b, c, id, cnt;
10+
int atag, btag;
11+
} A[maxn], B[maxn], C[maxn];
12+
int res[maxn];
13+
bool cmpa(const node& x, const node& y)
14+
{
15+
if (x.a != y.a) return x.a < y.a;
16+
if (x.b != y.b) return x.b < y.b;
17+
return x.c < y.c;
18+
}
19+
void init()
20+
{
21+
for (int i = 1; i <= n; ++i) A[i].id = i, A[i].cnt = 1;
22+
for (int i = 1; i <= n; ++i) res[i] = 0;
23+
std::sort(A + 1, A + 1 + n, cmpa);
24+
int tot = 0;
25+
for (int i = 2; i <= n; ++i)
26+
if (A[i].a == A[i - 1].a && A[i].b == A[i - 1].b && A[i].c == A[i - 1].c)
27+
A[i].cnt = A[i - 1].cnt + 1;
28+
else
29+
B[++tot] = A[i - 1];
30+
B[++tot] = A[n];
31+
n = tot;
32+
for (int i = 1; i <= n; ++i) A[i] = B[i];
33+
}
34+
void cdq2(int l, int r)
35+
{
36+
if(l == r) return;
37+
int mid = (l + r) >> 1;
38+
cdq2(l, mid), cdq2(mid + 1, r);
39+
// sort according to c
40+
for (int i = l; i <= mid; ++i) B[i].btag = 0;
41+
for (int i = mid + 1; i <= r; ++i) B[i].btag = 1;
42+
int p = l, q = mid + 1, k = l;
43+
while (p <= mid && q <= r)
44+
{
45+
if (B[p].c <= B[q].c)
46+
C[k++] = B[p++];
47+
else
48+
C[k++] = B[q++];
49+
}
50+
while (p <= mid) C[k++] = B[p++];
51+
while (q <= r) C[k++] = B[q++];
52+
for (int i = l; i <= r; ++i) B[i] = C[i];
53+
// now count the answer
54+
int num = 0;
55+
for (int i = l; i <= r; ++i)
56+
{
57+
if (B[i].atag && B[i].btag)
58+
res[B[i].id] += num;
59+
else if (!B[i].atag && !B[i].btag)
60+
num += B[i].cnt;
61+
}
62+
}
63+
void cdq(int l, int r)
64+
{
65+
if (l == r) return;
66+
int mid = (l + r) >> 1;
67+
cdq(l, mid), cdq(mid + 1, r);
68+
// now [l,mid] [mid+1,r] has been sorted according to b
69+
for (int i = l; i <= mid; ++i) A[i].atag = 0;
70+
for (int i = mid + 1; i <= r; ++i) A[i].atag = 1;
71+
// merge sort to get [l,r] sorted by b
72+
int p = l, q = mid + 1, k = l;
73+
while (p <= mid && q <= r)
74+
{
75+
if (A[p].b <= A[q].b)
76+
B[k++] = A[p++];
77+
else
78+
B[k++] = A[q++];
79+
}
80+
while (p <= mid) B[k++] = A[p++];
81+
while (q <= r) B[k++] = A[q++];
82+
// A should be sorted by b
83+
for(int i = l;i<=r;++i) A[i] = B[i];
84+
// now [l,r] sorted by b, cdq2 to get the answer
85+
cdq2(l, r);
86+
}
87+
} // namespace cdq
88+
int ans[maxn];
89+
int main()
90+
{
91+
int _n, k;
92+
using namespace cdq;
93+
scanf("%d%d", &cdq::n, &k);
94+
_n = n;
95+
for (int i = 1; i <= cdq::n; ++i)
96+
{
97+
int a, b, c;
98+
scanf("%d%d%d", &a, &b, &c);
99+
A[i].a = a, A[i].b = b, A[i].c = c;
100+
}
101+
cdq::init();
102+
cdq::cdq(1, cdq::n);
103+
// for(int i = 1;i<=cdq::n;++i)
104+
// printf("[%d]%d %d %d %d:%d\n",A[i].id,A[i].a,A[i].b,A[i].c,A[i].cnt, res[A[i].id] + A[i].cnt - 1);
105+
for (int i = 1; i <= cdq::n; ++i) ans[res[A[i].id] + A[i].cnt] += A[i].cnt;
106+
for (int i = 1; i <= _n; ++i) printf("%d\n", ans[i]);
107+
return 0;
108+
}

templates/cdq2.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include <algorithm>
2+
#include <cstdio>
3+
const int maxn = 2e5 + 100;
4+
namespace BitTree
5+
{
6+
int n;
7+
int sum[maxn], tag[maxn], now;
8+
inline void clear() { ++now; }
9+
inline void check(int x)
10+
{
11+
if (tag[x] != now) sum[x] = 0, tag[x] = now;
12+
}
13+
void add(int x, int k)
14+
{
15+
for (; x <= n; x += (x & -x)) check(x), sum[x] += k;
16+
}
17+
int ask(int x)
18+
{
19+
int res = 0;
20+
for (; x > 0; x -= (x & -x)) check(x), res += sum[x];
21+
return res;
22+
}
23+
} // namespace BitTree
24+
namespace cdq
25+
{
26+
int n;
27+
struct node
28+
{
29+
int a, b, c, id, cnt;
30+
} A[maxn], B[maxn], C[maxn];
31+
int res[maxn];
32+
bool cmpa(const node& x, const node& y)
33+
{
34+
if (x.a != y.a) return x.a < y.a;
35+
if (x.b != y.b) return x.b < y.b;
36+
return x.c < y.c;
37+
}
38+
void init()
39+
{
40+
for (int i = 1; i <= n; ++i) A[i].id = i, A[i].cnt = 1;
41+
for (int i = 1; i <= n; ++i) res[i] = 0;
42+
std::sort(A + 1, A + 1 + n, cmpa);
43+
int tot = 0;
44+
for (int i = 2; i <= n; ++i)
45+
if (A[i].a == A[i - 1].a && A[i].b == A[i - 1].b && A[i].c == A[i - 1].c)
46+
A[i].cnt = A[i - 1].cnt + 1;
47+
else
48+
B[++tot] = A[i - 1];
49+
B[++tot] = A[n];
50+
n = tot;
51+
for (int i = 1; i <= n; ++i) A[i] = B[i];
52+
}
53+
void cdq(int l, int r)
54+
{
55+
if (l == r) return;
56+
int mid = (l + r) >> 1;
57+
cdq(l, mid), cdq(mid + 1, r);
58+
// now [l,mid] [mid+1,r] has been sorted according to b
59+
// merge sort to get [l,r] sorted by b
60+
int p = l, q = mid + 1, k = l;
61+
while (p <= mid && q <= r)
62+
{
63+
if (A[p].b <= A[q].b)
64+
{
65+
BitTree::add(A[p].c, A[p].cnt);
66+
B[k++] = A[p++];
67+
}
68+
else
69+
{
70+
res[A[q].id] += BitTree::ask(A[q].c);
71+
B[k++] = A[q++];
72+
}
73+
}
74+
while (p <= mid) B[k++] = A[p++];
75+
while (q <= r) res[A[q].id] += BitTree::ask(A[q].c), B[k++] = A[q++];
76+
BitTree::clear();
77+
// A should be sorted by b
78+
for (int i = l; i <= r; ++i) A[i] = B[i];
79+
}
80+
} // namespace cdq
81+
int ans[maxn];
82+
int main()
83+
{
84+
int _n, k;
85+
using namespace cdq;
86+
scanf("%d%d", &cdq::n, &k);
87+
_n = n;
88+
BitTree::n = k;
89+
for (int i = 1; i <= cdq::n; ++i)
90+
{
91+
int a, b, c;
92+
scanf("%d%d%d", &a, &b, &c);
93+
A[i].a = a, A[i].b = b, A[i].c = c;
94+
}
95+
cdq::init();
96+
cdq::cdq(1, cdq::n);
97+
// for(int i = 1;i<=cdq::n;++i)
98+
// printf("[%d]%d %d %d %d:%d\n",A[i].id,A[i].a,A[i].b,A[i].c,A[i].cnt, res[A[i].id] + A[i].cnt - 1);
99+
for (int i = 1; i <= cdq::n; ++i) ans[res[A[i].id] + A[i].cnt] += A[i].cnt;
100+
for (int i = 1; i <= _n; ++i) printf("%d\n", ans[i]);
101+
return 0;
102+
}

0 commit comments

Comments
 (0)