码迷,mamicode.com
首页 > 其他好文 > 详细

P3710 方方方的数据结构

时间:2019-02-25 23:23:38      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:blank   cal   scanf   names   target   就是   build   amp   eve   

题面

• 如果没有撤销操作的话,它无非就是单纯的线段树。

• 如果加上撤销操作的话,它还可以是单纯的线段树。

• 把撤销操作看做是另一维的限制,那么修改与其对应的撤销就可以当做一个二维

  的修改。

• 将询问的点取出来后建一棵 K-D tree 就可以当做线段树操作了。

 

技术图片
  1 #include<bits/stdc++.h>
  2 #define ll long long
  3 #define ls son[u][0]
  4 #define rs son[u][1]
  5 #define p 998244353
  6 using namespace std;
  7 int n,m,root,K;
  8 ll tmp;
  9 ll sum[200050];
 10 ll add[200050];
 11 ll mul[200050];
 12 int t[200050],top;
 13 int opt,x[2],y[2];
 14 int L[200050][2];
 15 int R[200050][2];
 16 int val[200050][2];
 17 int son[200050][2];
 18 struct node
 19 {
 20     int opt,l,r,end;
 21     ll val;
 22 }num[200050];
 23 bool cmp(int a,int b)
 24 {
 25     return val[a][K]<val[b][K];
 26 }
 27 void pushup(int u)
 28 {
 29     add[u]=0;    mul[u]=1;
 30     for(int i=0;i<=1;++i)
 31     {
 32         L[u][i]=min(val[u][i],min(L[ls][i],L[rs][i]));
 33         R[u][i]=max(val[u][i],max(R[ls][i],R[rs][i]));
 34     }
 35 }
 36 void build(int &u,int l,int r,int k)
 37 {
 38     if(l>r)    return ;
 39     int mid=(l+r)>>1;    K=k;
 40     sort(t+l,t+r+1,cmp);
 41     u=t[mid];
 42     build(ls,l,mid-1,k^1);
 43     build(rs,mid+1,r,k^1);
 44     pushup(u);
 45 }
 46 void pushdown(int u)
 47 {
 48     if(mul[u]!=1)
 49     {
 50         (sum[ls]*=mul[u])%=p;
 51         (sum[rs]*=mul[u])%=p;
 52         (mul[ls]*=mul[u])%=p;
 53         (mul[rs]*=mul[u])%=p;
 54         (add[ls]*=mul[u])%=p;
 55         (add[rs]*=mul[u])%=p;
 56         mul[u]=1;
 57     }
 58     if(add[u]!=0)
 59     {
 60         (sum[ls]+=add[u])%=p;
 61         (sum[rs]+=add[u])%=p;
 62         (add[ls]+=add[u])%=p;
 63         (add[rs]+=add[u])%=p;
 64         add[u]=0;
 65     }
 66 }
 67 bool flagALL;
 68 bool flagALO;
 69 bool flagBIT;
 70 void check(int u)
 71 {
 72     flagALL=flagALO=flagBIT=true;
 73     for(int i=0;i<=1;++i)
 74         if(x[i]>L[u][i]||R[u][i]>y[i])
 75         {
 76             flagALL=false;
 77             if(x[i]>val[u][i]||val[u][i]>y[i])
 78             {
 79                 flagALO=false;
 80                 if(x[i]>R[u][i]||y[i]<L[u][i])
 81                     flagBIT=false;
 82             }
 83         }
 84 }
 85 void calc_add(int u)
 86 {
 87     if(!u)    return ;
 88     check(u);
 89     if(!flagBIT)
 90         return ;
 91     if(flagALO)
 92     {
 93         if(opt==1)
 94             (sum[u]+=tmp)%=p;
 95         else
 96             (sum[u]*=tmp)%=p;
 97     }
 98     if(flagALL)
 99     {
100         if(opt==1)
101             (add[u]+=tmp)%=p;
102         else
103         {
104             (add[u]*=tmp)%=p;
105             (mul[u]*=tmp)%=p;
106         }
107         return ;
108     }
109     pushdown(u);
110     calc_add(ls);
111     calc_add(rs);
112 }
113 void calc_ask(int u,int v)
114 {
115     if(!u)    return ;
116     if(val[v][0]<L[u][0]||val[v][0]>R[u][0]||val[v][1]<L[u][1]||val[v][1]>R[u][1])
117         return ;
118     if(u==v)
119     {
120         printf("%lld\n",sum[u]);
121         return ;
122     }
123     pushdown(u);
124     calc_ask(ls,v);
125     calc_ask(rs,v);
126 }
127 int main()
128 {
129     //freopen("ts.in","r",stdin);
130     //freopen("ts.out","w",stdout);
131     scanf("%d%d",&n,&m);
132     L[0][0]=200000;    R[0][0]=0;
133     L[0][1]=200000;    R[0][1]=0;
134     for(int i=1;i<=m;++i)
135     {
136         scanf("%d",&num[i].opt);
137         if(num[i].opt<=2)
138         {
139             scanf("%d%d%lld",&num[i].l,&num[i].r,&num[i].val);
140             num[i].end=m;
141         }
142         else if(num[i].opt==3)
143         {
144             scanf("%d",&val[i][1]);
145             val[i][0]=i;    ++top;
146             t[top]=i;    mul[i]=1;
147         }
148         else
149         {
150             scanf("%d",&num[i].end);
151             num[num[i].end].end=i;
152         }
153     }
154     build(root,1,top,0);
155     for(int i=1;i<=m;++i)
156         if(num[i].opt<=2)
157         {
158             opt=num[i].opt;
159             tmp=num[i].val;
160             tmp%=p;
161             x[0]=i;    x[1]=num[i].l;
162             y[0]=num[i].end;    y[1]=num[i].r;
163             calc_add(root);
164         }
165         else if(num[i].opt==3)
166             calc_ask(root,i);
167     return 0;
168 }
View Code

 

P3710 方方方的数据结构

标签:blank   cal   scanf   names   target   就是   build   amp   eve   

原文地址:https://www.cnblogs.com/wyher/p/10434489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!