zoukankan      html  css  js  c++  java
  • CF1140F

    题意:对于点集S,定义函数F(S)为对S不断扩展到不能扩展时S的点数。一次扩展定义为如果有一个平行于坐标轴的矩形的三个点在S中,则第四个点加入S。

    动态在S中加点删点,每次操作完后求F(S)的值。

    解:首先有个结论就是,把这些点用平行于坐标轴的线段连接起来,则E值为每个连通块的横坐标种数 * 纵坐标种数之和。

    线段树分治 + 可回退化并查集,O(nlog2n)。

      1 #include <bits/stdc++.h>
      2 
      3 typedef long long LL;
      4 const int N = 300010;
      5 
      6 struct Node {
      7     int x, y;
      8     Node(int X, int Y) {
      9         x = X;
     10         y = Y;
     11     }
     12 };
     13 
     14 std::map<int, int> mp[N];
     15 int n, m;
     16 LL ans[N];
     17 std::vector<Node> v[N << 2];
     18 
     19 namespace ufs {
     20     
     21     struct opt {
     22         int x, y;
     23         opt(){}
     24         opt(int X, int Y) {
     25             x = X, y = Y;
     26         }
     27     }stk[N * 4]; int top;
     28     
     29     int fa[N * 2], siz[N * 2], s1[N * 2], s2[N * 2], clock;
     30     LL tot, stk2[N];
     31     inline void init() {
     32         for(int i = 1; i < N; i++) {
     33             fa[i] = i;
     34             fa[i + N] = i + N;
     35             siz[i] = siz[i + N] = 1;
     36             s1[i] = s2[i + N] = 1;
     37             s2[i] = s1[i + N] = 0;
     38         }
     39         top = clock = 0;
     40         return;
     41     }
     42     int find(int x) {
     43         if(x == fa[x]) return x;
     44         return find(fa[x]);
     45     }
     46     inline LL cal(int x) {
     47         return 1ll * s1[x] * s2[x];
     48     }
     49     inline void merge(int x, int y) {
     50         x = find(x);
     51         y = find(y);
     52         if(x == y) return;
     53         if(siz[x] < siz[y]) {
     54             std::swap(x, y);
     55         }
     56         stk2[++clock] = tot;
     57         tot -= cal(x) + cal(y);
     58         stk[++top] = opt(y, fa[y]);
     59         fa[y] = x;
     60         stk[++top] = opt(x, siz[x]);
     61         siz[x] += siz[y];
     62         stk[++top] = opt(x, s1[x]);
     63         s1[x] += s1[y];
     64         stk[++top] = opt(x, s2[x]);
     65         s2[x] += s2[y];
     66         tot += cal(x);
     67         return;
     68     }
     69     inline void erase(int t) {
     70         while(clock > t) {
     71             tot = stk2[clock--];
     72             s2[stk[top].x] = stk[top].y;
     73             top--;
     74             s1[stk[top].x] = stk[top].y;
     75             top--;
     76             siz[stk[top].x] = stk[top].y;
     77             top--;
     78             fa[stk[top].x] = stk[top].y;
     79             top--;
     80         }
     81         return;
     82     }
     83 }
     84 
     85 void add(int L, int R, Node x, int l, int r, int o) {
     86     if(L <= l && r <= R) {
     87         v[o].push_back(x);
     88         return;
     89     }
     90     int mid = (l + r) >> 1;
     91     if(L <= mid) {
     92         add(L, R, x, l, mid, o << 1);
     93     }
     94     if(mid < R) {
     95         add(L, R, x, mid + 1, r, o << 1 | 1);
     96     }
     97     return;
     98 }
     99 
    100 void solve(int l, int r, int o) {
    101     int now = ufs::clock;
    102     for(int i = 0; i < (int)v[o].size(); i++) {
    103         ufs::merge(v[o][i].x, v[o][i].y + N);
    104         //printf("[%d %d] merge %d %d 
    ", l, r, v[o][i].x, v[o][i].y);
    105     }
    106     if(l == r) {
    107         ans[r] = ufs::tot;
    108         ufs::erase(now);
    109         return;
    110     }
    111     int mid = (l + r) >> 1;
    112     solve(l, mid, o << 1);
    113     solve(mid + 1, r, o << 1 | 1);
    114     ufs::erase(now);
    115     return;
    116 }
    117 
    118 int main() {
    119     ufs::init();
    120     scanf("%d", &n);
    121     for(int i = 1, x, y; i <= n; i++) {
    122         scanf("%d%d", &x, &y);
    123         if(mp[x][y]) {
    124             add(mp[x][y], i - 1, Node(x, y), 1, n, 1);
    125             //printf("add : (%d %d) [%d %d] 
    ", x, y, mp[x][y], i - 1);
    126             mp[x][y] = 0;
    127         }
    128         else {
    129             mp[x][y] = i;
    130         }
    131     }
    132     std::map<int, int>::iterator it;
    133     for(int i = 1; i < N; i++) {
    134         for(it = mp[i].begin(); it != mp[i].end(); it++) {
    135             if(it->second) {
    136                 add(it->second, n, Node(i, it->first), 1, n, 1);
    137                 //printf("add : (%d %d) [%d %d] 
    ", i, it->first, it->second, n);
    138             }
    139         }
    140     }
    141     
    142     solve(1, n, 1);
    143     for(int i = 1; i <= n; i++) {
    144         printf("%lld ", ans[i]);
    145     }
    146     return 0;
    147 }
    AC代码
  • 相关阅读:
    Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor
    Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security
    IdentityServer4 And AspNetCore.Identity Get AccessToken 问题
    Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute
    Java Spring Boot VS .NetCore (七) 配置文件
    Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtml
    Java Spring Boot VS .NetCore (五)MyBatis vs EFCore
    Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore
    Java Spring Boot VS .NetCore (三)Ioc容器处理
    Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10937859.html
Copyright © 2011-2022 走看看