zoukankan      html  css  js  c++  java
  • Luogu5280 [ZJOI2019] 线段树 【线段树】

    题目分析:

    这题除了分类讨论就没啥了。。。

    容易发现问题实际就是所有操作选和不选按顺序执行的所有答案和。考虑每个点在多少种情况下会有tag。

    那么,考虑新插入一个[l,r],所有有交集的点都会被清空,所以这些点答案不变。

    然后考虑有交集的点中间[l',r']是子集关系的点,这些点答案并不是不变,而是答案加了$2^{cnt-1}$,$cnt$为已执行的1操作数。

    然后没被遍历到的点答案*2.

    然后遍历到的点中间没有任何交集的点,答案数加的就是前面的操作方案中他到根的路径中间有tag的这个点的数量。

    这个我们再建一个线段树,然后分类讨论。

    对于扫到的终点和它下面的点,答案加上$2^{cnt-1}$,对于经过的有交集的点,答案不变。对于剩下遍历到的点和没遍历到的点,答案*2。

    这是因为tag会往下传,不会影响其它的答案。

    以上用lazytag实现

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int mod = 998244353;
      5 const int maxn = 102000;
      6 
      7 int n,m,cnt;
      8 
      9 int T1[maxn<<3],D1[maxn<<3],lazy1[maxn<<3];
     10 int D2[maxn<<3],M2[maxn<<3],A2[maxn<<3];
     11 int pw2[maxn];
     12 
     13 void push_down(int now){
     14     T1[now<<1]=1ll*T1[now<<1]*lazy1[now]%mod;
     15     T1[now<<1|1]=1ll*T1[now<<1|1]*lazy1[now]%mod;
     16     D1[now<<1]=1ll*D1[now<<1]*lazy1[now]%mod;
     17     D1[now<<1|1]=1ll*D1[now<<1|1]*lazy1[now]%mod;
     18     lazy1[now<<1] = 1ll*lazy1[now<<1]*lazy1[now]%mod;
     19     lazy1[now<<1|1] = 1ll*lazy1[now<<1|1]*lazy1[now]%mod;
     20     lazy1[now] = 1;
     21 }
     22 
     23 void modify1(int now,int tl,int tr,int l,int r){
     24     if(tl > r || tr < l){
     25     T1[now]*=2;T1[now]%=mod; //D1[now]*=2;D1[now]%=mod;
     26     T1[now] -= D1[now]; T1[now] += mod; T1[now] %= mod;
     27     lazy1[now] *= 2; lazy1[now] %= mod;
     28     return;
     29     }
     30     if(tl >= l && tr <= r){
     31     T1[now] = ((2ll*T1[now]%mod-D1[now]+mod)%mod+pw2[cnt-1])%mod;
     32     D1[now] = (D1[now]+pw2[cnt-1])%mod;
     33     lazy1[now] = 2ll*lazy1[now]%mod;
     34     return;
     35     }
     36     if(lazy1[now]!=1) push_down(now);
     37     int mid = (tl+tr)/2;
     38     modify1(now<<1,tl,mid,l,r); modify1(now<<1|1,mid+1,tr,l,r);
     39     T1[now] = (1ll*T1[now<<1]+T1[now<<1|1]+D1[now])%mod;
     40 }
     41 
     42 void pdm(int now){
     43     D2[now<<1] = 1ll*M2[now]*D2[now<<1]%mod;
     44     D2[now<<1|1] = 1ll*M2[now]*D2[now<<1|1]%mod;
     45     M2[now<<1] = 1ll*M2[now<<1]*M2[now]%mod;
     46     M2[now<<1|1] = 1ll*M2[now<<1|1]*M2[now]%mod;
     47     A2[now<<1] = 1ll*A2[now<<1]*M2[now]%mod;
     48     A2[now<<1|1] = 1ll*A2[now<<1|1]*M2[now]%mod;
     49     M2[now] = 1;
     50 }
     51 
     52 void pda(int now){
     53     D2[now<<1] = (D2[now<<1]+A2[now])%mod;
     54     D2[now<<1|1] = (D2[now<<1|1]+A2[now])%mod;
     55     A2[now<<1] = (A2[now<<1]+A2[now])%mod;
     56     A2[now<<1|1] = (A2[now<<1|1]+A2[now])%mod;
     57     A2[now] = 0;
     58 }
     59 
     60 stack<int> sta;
     61 void add1(int now,int dt){
     62     int pp = now;
     63     while(pp){sta.push(pp); pp >>= 1;}
     64     while(!sta.empty()){
     65     if(lazy1[sta.top()]) push_down(sta.top());
     66     T1[sta.top()] += dt; T1[sta.top()] %= mod;
     67     sta.pop();
     68     }
     69     D1[now] += dt; D1[now] %= mod;
     70 }
     71 
     72 void modify2(int now,int tl,int tr,int l,int r){
     73     if(tl > r || tr < l){
     74     add1(now,D2[now]);D2[now] *=2; D2[now] %= mod;
     75     M2[now] = M2[now]*2%mod; A2[now] = A2[now]*2%mod;
     76     return;
     77     }
     78     if(tl >= l && tr <= r){
     79     D2[now] += pw2[cnt-1]; D2[now] %= mod;
     80     A2[now]+=pw2[cnt-1];A2[now]%=mod;return;
     81     }
     82     if(M2[now] != 1) pdm(now);
     83     if(A2[now]) pda(now);
     84     int mid = (tl+tr)/2;
     85     modify2(now<<1,tl,mid,l,r);
     86     modify2(now<<1|1,mid+1,tr,l,r);
     87 }
     88 
     89 int main(){
     90     scanf("%d%d",&n,&m);
     91     for(int i=1;i<=4*n;i++) lazy1[i] = 1,M2[i] = 1;
     92     pw2[0] = 1;
     93     for(int i=1;i<=m;i++) pw2[i] = 2*pw2[i-1]%mod;
     94     for(int i=1;i<=m;i++){
     95     int cas; scanf("%d",&cas);
     96     if(cas == 2){printf("%d
    ",T1[1]);}
     97     else{
     98         int l,r; scanf("%d%d",&l,&r);
     99         cnt++;
    100         modify1(1,1,n,l,r);
    101         modify2(1,1,n,l,r);
    102     }
    103     }
    104 }
  • 相关阅读:
    搜索入门练习题3 全组合 题解
    搜索入门练习题1 素数环 题解
    搜索入门练习题2 全排列 题解
    二分 大纲
    凸包
    快速幂&矩阵快速幂
    最长不下降子序列的优化
    poj 3190 Stall Reservations
    poj 2431 Expedition

  • 原文地址:https://www.cnblogs.com/Menhera/p/10895715.html
Copyright © 2011-2022 走看看