1. 程式人生 > >【題解】洛谷P1975排序

【題解】洛谷P1975排序

space getchar() class std -- names char 圖書管理員 wap

分塊,註意重復的值之間的處理。跟普通分塊的操作一樣的啦,具體可以參見‘不勤勞的圖書管理員’。

#include <bits/stdc++.h>
using namespace std;
#define maxn 500000
#define lowbit(i) i & (-i) 
#define int long long
int n, m, cnt, ans, B, c[200][maxn];
struct node
{
    int num, id, rank;
}a[30000];

int read()
{
    int x = 0;
    char c;
    c = getchar();
    
while(c < 0 || c > 9) c = getchar(); while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = getchar(); return x; } int Get_ans(int x, int y) { if(a[x].rank < a[y].rank) return 1; else if(a[x].rank > a[y].rank) return -1; return 0; } bool cmp1(node a, node b) {
if(a.num != b.num) return a.num < b.num; return a.id < b.id; } bool cmp2(node a, node b) { return a.id < b.id; } void update(int opt, int x, int sum) { if(!x) return; for(int i = x; i <= cnt; i += lowbit(i)) c[opt][i] += sum; } int query(int opt, int x) { if
(x < 0) return 0; int ans = 0; for(int i = x; i; i -= lowbit(i)) ans += c[opt][i]; return ans; } signed main() { n = read(); B = sqrt(n); for(int i = 1; i <= n; i ++) a[i].num = read(), a[i].id = i; sort(a + 1, a + 1 + n, cmp1); a[0].rank = 1; for(int i = 1; i <= n; i ++) if(a[i].num == a[i - 1].num) a[i].rank = a[i - 1].rank; else a[i].rank = ++ cnt; sort(a + 1, a + 1 + n, cmp2); for(int i = 1; i <= n; i ++) update(i / B, a[i].rank, 1); for(int i = n; i >= 1; i --) { ans += query(n / B + 1, a[i].rank - 1); update(n / B + 1, a[i].rank, 1); } m = read(); cout << ans << endl; for(int i = 1; i <= m; i ++) { int x = read(), y = read(); if(x > y) swap(y, x); int p = x / B, q = y / B; if(a[x].rank < a[y].rank) ans ++; else if(a[x].rank > a[y].rank) ans --; if(p == q) { for(int i = x + 1; i < y; i ++) ans += Get_ans(x, i) + Get_ans(i, y); swap(a[x], a[y]); printf("%lld\n", ans); continue; } for(int i = x + 1; i < (p + 1) * B; i ++) if(i <= n) ans += Get_ans(x, i) + Get_ans(i, y); for(int i = q * B; i < y; i ++) ans += Get_ans(i, y) + Get_ans(x, i); for(int i = p + 1; i < q; i ++) { ans = (ans - query(i, a[x].rank - 1) + query(i, a[y].rank - 1)); ans = (ans - query(i, a[x].rank) + query(i, a[y].rank)); } update(p, a[x].rank, -1), update(q, a[y].rank, -1); update(q, a[x].rank, 1), update(p, a[y].rank, 1); swap(a[x], a[y]); printf("%lld\n", ans); } return 0; }

【題解】洛谷P1975排序