显然,能从$l$到$r$当且仅当$[l,r)$中的灯全部都亮,以下不妨令询问的$r$全部减1

当修改节点$x$时,找到包含$x$的极大的灯(除$x$以外)全部都亮的区间$[l,r]$,即令$l_{0}\in [l,x]$且$r_{0}\in [x,r]$的询问答案加上或减去$\Delta t$(其中$\Delta t$为该询问时刻-当前修改时刻)

可以将其看作一个一次函数的形式(关于询问时刻,当然斜率只为0或1),那么问题即变为支持矩阵加(可负)和单点查询,差分后也相当于是三维偏序问题,cdq分治+线段树即可

时间复杂度为$o(n\log^{2}n)$,可以通过

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 300005
4 #define L (k<<1)
5 #define R (L+1)
6 #define mid (l+r>>1)
7 #define pii pair<int,int>
8 #define mp make_pair
9 #define fi first
10 #define se second
11 struct Data{
12 int p,x,y;
13 pii z;
14 }a[N<<3];
15 vector<Data>v;
16 pii sum[N<<2];
17 int E,n,m,q,t,x,y,vis[N],ans[N],f[N<<2];
18 char s[N];
19 bool cmp(Data x,Data y){
20 return (x.x>y.x)||(x.x==y.x)&&(x.p<y.p);
21 }
22 pii merge(pii x,pii y){
23 return mp(x.fi+y.fi,x.se+y.se);
24 }
25 void update(int k,int l,int r,int x,pii y){
26 sum[k]=merge(sum[k],y);
27 if (l==r)return;
28 if (x<=mid)update(L,l,mid,x,y);
29 else update(R,mid+1,r,x,y);
30 }
31 pii query(int k,int l,int r,int x,int y){
32 if ((l>y)||(x>r))return mp(0,0);
33 if ((x<=l)&&(r<=y))return sum[k];
34 return merge(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
35 }
36 void update(int k,int l,int r,int x){
37 if (l==r){
38 f[k]^=1;
39 return;
40 }
41 if (x<=mid)update(L,l,mid,x);
42 else update(R,mid+1,r,x);
43 f[k]=f[L]+f[R];
44 }
45 int getl(int k,int l,int r,int x){
46 if ((l>=x)||(r<x)&&(f[k]==r-l+1))return 0;
47 if (l==r)return l;
48 int ans=getl(R,mid+1,r,x);
49 if (ans)return ans;
50 return getl(L,l,mid,x);
51 }
52 int getr(int k,int l,int r,int x){
53 if ((r<=x)||(l>x)&&(f[k]==r-l+1))return n+1;
54 if (l==r)return l;
55 int ans=getr(L,l,mid,x);
56 if (ans<=n)return ans;
57 return getr(R,mid+1,r,x);
58 }
59 void update(int k,int id){
60 update(1,1,n,k);
61 vis[k]^=1;
62 int l=getl(1,1,n,k)+1,r=getr(1,1,n,k)-1;
63 pii o1=mp(1,-id),o2=mp(-1,id);
64 if (!vis[k])swap(o1,o2);
65 a[++t]=Data{0,k,r,o1};
66 if (k>1)a[++t]=Data{0,k,k-1,o2};
67 if (l>1)a[++t]=Data{0,l-1,r,o2};
68 if ((k>1)&&(l>1))a[++t]=Data{0,l-1,k-1,o1};
69 }
70 void query(int x,int y,int id){
71 a[++t]=Data{1,x,y,mp(id,++q)};
72 }
73 void calc(int l,int r){
74 if (l==r)return;
75 v.clear();
76 for(int i=l;i<=mid;i++)
77 if (!a[i].p)v.push_back(a[i]);
78 for(int i=mid+1;i<=r;i++)
79 if (a[i].p)v.push_back(a[i]);
80 sort(v.begin(),v.end(),cmp);
81 for(int i=0;i<v.size();i++)
82 if (!v[i].p)update(1,1,n,v[i].y,v[i].z);
83 else{
84 pii o=query(1,1,n,v[i].y,n);
85 ans[v[i].z.se]+=o.fi*v[i].z.fi+o.se;
86 }
87 for(int i=0;i<v.size();i++)
88 if (!v[i].p)update(1,1,n,v[i].y,mp(-v[i].z.fi,-v[i].z.se));
89 calc(l,mid);
90 calc(mid+1,r);
91 }
92 int main(){
93 scanf("%d%d%s",&n,&m,s+1);
94 for(int i=1;i<=n;i++)
95 if (s[i]=='1')update(i,0);
96 for(int i=1;i<=m;i++){
97 scanf("%s%d",s,&x);
98 if (s[0]=='t')update(x,i);
99 else{
100 scanf("%d",&y);
101 query(x,y-1,i);
102 }
103 }
104 calc(1,t);
105 for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
106 }

最新文章

  1. Design and Analysis of Algorithms_Divide-and-Conquer
  2. htmlFormat
  3. C语言中内存操作函数
  4. 图片和Base64之间的转换
  5. windows下打包react-native应用程序
  6. 记CVTE2014年春季招聘实习生求职历程
  7. IE调试方法(一)&lt;转&gt;
  8. 转Unity 异常操作
  9. PHP接收JSON格式的数据
  10. ABP中动态WebAPI原理解析
  11. SQLSERVER异机备份
  12. 2017最新最稳定的合买彩票源码asp+sql2008 新增PK式彩种+全新界面
  13. 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索
  14. H5+混合移动app应用开发——开篇
  15. 开源视频平台:MediaCore(MediaDrop)
  16. x86汇编语言实践(3)
  17. echarts图表
  18. Android Studio3.1.2运行模拟器出错Emulator:emulator:ERROR:x86 emulation currently requires hardware acceleration!
  19. Java虚拟机-JVM各种参数配置大全详细
  20. caffe中全卷积层和全连接层训练参数如何确定

热门文章

  1. 利用Jackson序列化实现数据脱敏
  2. sarama的消费者组分析、使用
  3. CF911G Mass Change Queries(线段树+暴力)
  4. 2020.5.4-ICPC Pacific Northwest Regional Contest 2019
  5. 掌握BeanShell,轻松处理jmeter中的数据
  6. 初探JavaScript PDF blob转换为Word docx方法
  7. javascript高级程序设计第三版书摘
  8. Vue2源码解读 - 响应式原理及简单实现
  9. 【UE4 C++】读写Text文件 FFileHelper
  10. 【Deeplearning.ai 】吴恩达深度学习笔记及课后作业目录