牛客集训 湖南省赛E题 Grid 动态开点线段树

国庆牛客集训的题,正好准备好好训练线段树,想起来就补一下。

题意很简单,两种操作行合并或者列合并,每个操作后计算有多少个子块。

这题应该先推导公式,行操作或者列操作只有一种的时候,很简单,总数就是n*m - 有多少行或列合并了*一列多少格子m或者一行多少格子n + 合并的行或者列数。

两种都在,就需要结合图示来理解一下,简单的容斥一下,总数就是n*m - 行列各自算一遍上述的, 再加上行列重叠的,再加上最终行列合成的一块。

 

然后根据公式,

我们发现这里需要维护的是1~n和m的行或者列,有多少行或者列已经被合并了,n和m最大到1e9,而且不能离散化,(离散化我也不会,😀),又是区间信息合并,就用到了动态开点的线段树。

动态开点的线段树只开我们所需要用到部分,大大节省了空间。

而这里,每次更新ql和qr部分,我只需要用线段树的结点记录区间的长度,最后合并到最大的区间s[1]即可,cnt记录总区间数和新开的左右子树的编号,ls[]和rs[]分别存储左右子树编号,rt除了第一次是0,后来每次更新都是从1开始往下查找的,跟普通线段树一样的初始结点编号。

 

代码:

 1 #include <bits/stdc++.h>
 2 #define debug(x) cout << #x << ": " << x << endl
 3 using namespace std;
 4 typedef long long ll;
 5 const int MAXN=2e5+7;
 6 const int INF=0x3f3f3f3f;
 7 const int MOD=1e9+7;
 8 
 9 struct tree
10 {
11     int s[MAXN],ls[MAXN],rs[MAXN],cnt=0,rt=0;
12     void init()
13     {
14         for(int i=0;i<=cnt;++i)
15             s[i]=ls[i]=rs[i]=0;
16         cnt=rt=0;
17     }
18     void update(int &o,int l,int r,int ql,int qr)
19     {
20         if(!o) o=++cnt;
21         //debug(o);
22         if(s[o]==r-l+1) return;
23         if(ql<=l && r<=qr) {s[o]=r-l+1;return;}
24         int mid=l+r>>1;
25         if(ql<=mid) update(ls[o],l,mid,ql,qr);
26         if(qr>mid) update(rs[o],mid+1,r,ql,qr);
27         s[o]=s[ls[o]]+s[rs[o]];
28     }
29 }row,col;
30 
31 int main()
32 {
33     int n,m,q;
34     while(~scanf("%d%d%d",&n,&m,&q))
35     {
36         row.init();col.init();
37         int op,l,r;
38         while(q--)
39         {
40             scanf("%d%d%d",&op,&l,&r);
41             if(op==1) row.update(row.rt,1,n,l,r);
42             else col.update(col.rt,1,m,l,r);
43             ll ans=0;
44             //debug(col.s[1]);
45             //debug(row.s[1]);
46             if(row.s[1]==0) ans=1ll*n*m-1ll*col.s[1]*n+1ll*col.s[1];
47             else if(col.s[1]==0) ans=1ll*n*m-1ll*row.s[1]*m+1ll*row.s[1];
48             else ans=1ll*n*m-1ll*col.s[1]*n-1ll*row.s[1]*m+1ll*row.s[1]*col.s[1]+1;
49             printf("%lld\n",ans);
50         }
51     }
52     return 0;
53 }
View Code

 

posted @ 2019-11-04 16:55  Zzqf  阅读(156)  评论(0)    收藏  举报