每个时刻都形成若干段满足段内任意两点可达。将其视为若干正方形。则查询相当于求历史上某点被正方形包含的时刻数量。并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就是裸的三维偏序,cdq分治+树状数组即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 300010
#define mp(x,y) make_pair((x),(y))
#define fi first
#define se second
#define time se.fi
#define ans se.se
#define val se.se
#define left fi.fi
#define right fi.se
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
typedef pair<int,int> pii;
typedef pair<pii,pii> ppp;
int n,m,t,u,v,a[N],tree[N];
char s[N];
set<ppp> seg;
ppp b[N<<1],q[N];
pii o;
struct data
{
ppp x;int op;
bool operator <(const data&a) const
{
return x.time<a.x.time||x.time==a.x.time&&x.fi<a.x.fi||x.time==a.x.time&&x.fi==a.x.fi&&op<a.op;
}
}c[N*3],d[N*3];
void add(int k,int x){while (k<=n) tree[k]+=x,k+=k&-k;}
int query(int k){int s=0;while (k) s+=tree[k],k-=k&-k;return s;}
void solve(int l,int r)
{
if (l==r) return;
int mid=l+r>>1;
solve(l,mid);
solve(mid+1,r);
int cur=l-1;
for (int i=mid+1;i<=r;i++)
if (c[i].op==1)
{
while (cur<mid&&(c[cur+1].op==1||c[cur+1].x.left<=c[i].x.left))
{
cur++;
if (c[cur].op==0) add(c[cur].x.right,c[cur].x.val);
}
c[i].x.ans+=query(c[i].x.right);
}
for (;cur>=l;cur--) if (c[cur].op==0) add(c[cur].x.right,-c[cur].x.val);
int i=l,j=mid+1;
for (int k=l;k<=r;k++)
if (i<=mid&&(j>r||c[i].x.left<c[j].x.left)) d[k]=c[i++];else d[k]=c[j++];
for (int k=l;k<=r;k++) c[k]=d[k];
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();
scanf("%s",s+1);
for (int i=1;i<=n;i++) a[i]=s[i]-'0';
if (!a[1]) seg.insert(mp(o,o));
for (int i=1;i<=n;i++)
if (a[i])
{
int t=i;
while (t<n&&a[t+1]==1) t++;
seg.insert(mp(mp(i-1,t),o));
i=t;
}
else if (!a[i+1]) seg.insert(mp(mp(i,i),o));
for (int i=1;i<=m;i++)
{
/*for (auto it=seg.begin();it!=seg.end();it++)
cout<<(*it).left<<' '<<(*it).right<<' '<<(*it).time<<endl;
cout<<endl;*/
char c=getc();
if (c=='q')
{
int l=read()-1,r=read()-1;
q[++t]=mp(mp(l,r),mp(i-1,0));
auto it=seg.upper_bound(mp(mp(l,n+1),o));
if (it!=seg.begin())
{
it--;
if ((*it).right>=r) q[t].ans=i-(*it).time;
}
}
else
{
int x=read();
if (a[x])
{
auto it=seg.lower_bound(mp(mp(x,0),o));it--;
ppp tmp=*it;seg.erase(it);
b[++u]=mp(tmp.fi,mp(i-1,i-tmp.time));
seg.insert(mp(mp(tmp.left,x-1),mp(i,0)));
seg.insert(mp(mp(x,tmp.right),mp(i,0)));
}
else
{
auto it=seg.lower_bound(mp(mp(x,0),o));
auto it2=it;it2--;
ppp tmp=*it;seg.erase(it);
ppp tmp2=*it2;seg.erase(it2);
b[++u]=mp(tmp.fi,mp(i-1,i-tmp.time));
b[++u]=mp(tmp2.fi,mp(i-1,i-tmp2.time));
seg.insert(mp(mp(tmp2.left,tmp.right),mp(i,0)));
}
a[x]^=1;
}
}
n++;
for (int i=1;i<=t;i++) q[i].right=n-q[i].right;
for (int i=1;i<=u;i++) b[i].right=n-b[i].right;
/*for (int i=1;i<=t;i++) cout<<q[i].left<<' '<<q[i].right<<' '<<q[i].time<<' '<<q[i].ans<<endl;
cout<<endl;
for (int i=1;i<=u;i++) cout<<b[i].left<<' '<<b[i].right<<' '<<b[i].time<<' '<<b[i].val<<endl;*/
//求left<=q[i].left right<=q[i].right time<=q[i].time 的权值和
/*for (int i=1;i<=t;i++)
for (int j=1;j<=u;j++)
if (b[j].left<=q[i].left&&b[j].right<=q[i].right&&b[j].time<=q[i].time) q[i].ans+=b[j].val;*/
for (int i=1;i<=t;i++) c[++v].x=q[i],c[v].op=1;
for (int i=1;i<=u;i++) c[++v].x=b[i],c[v].op=0;
sort(c+1,c+v+1);
solve(1,v);
sort(c+1,c+v+1);
for (int i=1;i<=v;i++) if (c[i].op==1) printf("%d\n",c[i].x.ans);
return 0;
//NOTICE LONG LONG!!!!!
}

  

LOJ3146 APIO2019路灯(cdq分治+树状数组)的更多相关文章

  1. 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组

    [BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...

  2. BZOJ 1176 Mokia CDQ分治+树状数组

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

  3. 【bzoj3262】陌上花开 CDQ分治+树状数组

    题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...

  4. 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组

    题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...

  5. BZOJ 2683 简单题 cdq分治+树状数组

    题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...

  6. BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组

    考虑答案的构成,发现是一个有限制条件的偏序问题. 然后三个维度的DP,可以排序.CDQ.树状数组各解决一维. #include <map> #include <cmath> # ...

  7. BZOJ1176---[Balkan2007]Mokia (CDQ分治 + 树状数组)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1176 CDQ第一题,warush了好久.. CDQ分治推荐论文: 1 <从<C ...

  8. Hdu4742-Pinball Game 3D(cdq分治+树状数组)

    Problem Description RD is a smart boy and excel in pinball game. However, playing common 2D pinball ...

  9. hdu 5126 stars cdq分治套cdq分治+树状数组

    题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...

随机推荐

  1. 【cf contest 1119 G】Get Ready for the Battle

    题目 你有\(n\)个士兵,需要将他们分成\(m\)组,每组可以为0: 现在这些士兵要去攻打\(m\)个敌人,每个敌人的生命值为\(hp_i\) : 一轮游戏中一组士兵选定一个攻打的敌人,敌人生命值- ...

  2. 最近在弄ionic3的时候遇到的一些问题(遇到就更新)

    问题一(install提示errno -4048 和管理员权限) npm install npm ERR! code EPERM npm ERR! errno - npm ERR! syscall u ...

  3. vim 注释颜色

    方法一 修改 vim 配置文件 /etc/vim/vimrc (1)用vim打开 /etc/vim/vimrc文件 (2)按大写 ‘G’ 到最后一行,插入   hi comment ctermfg=6 ...

  4. C++之宏、extern关键字与多线程

    理解C++ 宏 1.特殊字符 考虑下面的需求,程序中多处使用文本字符串.我们知道文本字符串前后都要加上双引号,我很讨厌输入双引号.有没有好的办法呢?根据常识,使用下面的宏: #define Str(x ...

  5. C# 最简单的使程序单进程运行的方法

    1.代码1 static void Main() { Process current = Process.GetCurrentProcess(); Process[] processes = Proc ...

  6. 安装EOS合约工具eosio.cdt

    安装: 安装完之后 会产生 eosio-cpp_, eosio-cc, eosio-ld, eosio-pp, and _eosio_abigen (These are the C++ compile ...

  7. filebeat获取nginx的access日志配置

    filebeat获取nginx的access日志配置 产生nginx日志的服务器即生产者服务器配置: 拿omp.chinasoft.com举例: .nginx.conf主配置文件添加日志格式 log_ ...

  8. git 如何同步本地tag与远程tag

    问题场景:同事A在本地创建tagA并push同步到了远程->同事B在本地拉取了远程tagA(git fetch)->同事A工作需要将远程标签tagA删除->同事B用git fetch ...

  9. Swift编码总结6

    1.UILabel的minimumScaleFactor: 需要UIlabel根据字数多少来减小字体大小,使得UIlabel能够显示全所有的文字.你需要做的就是设置minimumScaleFactor ...

  10. [LeetCode] 204. Count Primes 计数质数

    Description: Count the number of prime numbers less than a non-negative number, n click to show more ...