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("\n"); 58 return 0; 59 }
时间: 2024-11-07 00:32:08