Codeforces 755D(思维+线段树)

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

从X到X+k点,其实只要求从X到X+k之间的点有多少条线超过X——X+K这条线就行,一开始直接暴力,就时间超时了,而用线段树维护就快多了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 #define N 1000010
 5 #define INF 0x3f3f3f3f
 6 #define lson rt<<1, l, m
 7 #define rson rt<<1|1, m+1, r
 8 LL tree[N<<2];
 9 
10 void pushup(int rt) { tree[rt] = tree[rt<<1] + tree[rt<<1|1]; }
11 
12 void update(int rt, int l, int r, int id) {
13     if(l == r && l == id) {
14         tree[rt]++;
15         return ;
16     }
17     int m = (l + r) >> 1;
18     if(id <= m) update(lson, id);
19     else update(rson, id);
20     pushup(rt);
21 }
22 
23 LL query(int rt, int l, int r, int L, int R) {
24     LL ans = 0;
25     if(L <= l && r <= R) return tree[rt];
26     int m = (l + r) >> 1;
27     if(L <= m) ans += query(lson, L, R);
28     if(m < R) ans += query(rson, L, R);
29     return ans;
30 }
31 
32 LL getsum(int l, int r, int n) {
33     LL ans = 0;
34     if(l > r) {
35         ans += query(1, 1, n, l, n);
36         ans += query(1, 1, n, 1, r);
37     } else {
38         ans += query(1, 1, n, l, r);
39     }
40     return ans;
41 }
42 
43 int main()
44 {
45     int n, k;
46     cin >> n >> k;
47     int now = 1 + k, pre;
48     if(k > n / 2) k = n - k;
49     LL res = 1;
50     for(int i = 1; i <= n; i++) {
51         pre = now; update(1, 1, n, pre);
52         now += k; if(now > n) now -= n;
53         res += getsum(pre, now, n) - 1;
54         printf("%lld ",(i==n) ? res : res+1);
55         update(1, 1, n, now);
56     }
57     printf("
");
58     return 0;
59 }
原文地址:https://www.cnblogs.com/xingkongyihao/p/6789134.html