P5445 [APIO2019] 路灯

调了两百年。

首先切换灯的状态等价于断开/连接连续段。

·断开连续段 \([l,r]\to [l,x],(x,r]\) 则对询问 \((a,b),a\in [l,x],b\in(x,r]\) 到此时刻不连通。

·连接连续段 \([l,x],(x,r]\to [l,r]\) 则对询问 \((a,b),a\in [l,x],b\in(x,r]\) 到此时刻连通。

考虑差分,连通时对询问 \(-t\),不连通时 \(+t\) 刚好表示了这段连通的时刻。若询问时刻连通则需要手动 \(+t\),因为最后一段连通的时刻还未计算。

所以问题转为矩阵加,单点查,加上时间这一维就是三维偏序,cdq 解决即可。

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define fin(x) freopen(#x".in","r",stdin)
#define fout(x) freopen(#x".out","w",stdout)
#define fr(x) fin(x),fout(x);
#define Fr(x,y) fin(x),fout(y)
#define INPUT(_1,_2,FILE,...) FILE
#define IO(...) INPUT(__VA_ARGS__,Fr,fr)(__VA_ARGS__)
using namespace std;
using namespace __gnu_pbds;
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define ll long long
#define ull unsigned long long
#define intz(x,y) memset((x),(y),sizeof((x)))
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
#define tup(x) array<int,(x)>
inline ll read(){
    ll x=0,f=1;char ch=nc();
    while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}
    while(ch>=48&&ch<=57)x=x*10+ch-48,ch=nc();
   	return x*f;
}
//void write(int x){cout<<x<<' ';}
//void write(pii x){cout<<"P("<<x.fi<<','<<x.se<<")\n";}
//void write(vector<auto>x){for(auto i:x)write(i);cout<<'\n';}
//void write(auto *a,int l,int r){for(int i=l;i<=r;i++)write(a[i]);cout<<'\n';}
inline ll lowbit(ll x){return x&-x;}
#define pcount(x) __builtin_popcount(x)
inline void cmx(ll &x,ll y){if(y>x)x=y;}
inline void cmn(ll &x,ll y){if(y<x)x=y;}
const int mod=998244353;
ll qp(ll x,int y){ll res=1;for(;y;x=x*x%mod,y>>=1)if(y&1)res=res*x%mod;return res;}
const int N=3e5+5,inf=1e9;
#define b(x) (x).begin()
set<pii>w;char s[N];int ans[N],t[N],n,m;
struct node{int x,y,v;};vector<node>q;
bool cmp(node x,node y){return x.x<y.x;}
void upd(int x,int v){for(;x<=n+1;x+=lowbit(x))t[x]+=v;}
int ask(int x){int res=0;for(;x;x-=lowbit(x))res+=t[x];return res;}
void cdq(int L,int R){
	if(L>=R)return;int mid=L+R>>1;
	cdq(L,mid),cdq(mid+1,R);
	sort(b(q)+L,b(q)+1+mid,cmp),
	sort(b(q)+mid+1,b(q)+1+R,cmp);
	vector<pii>tmp;
	for(int l=L,r=mid+1;r<=R;r++){
		while(l<=mid&&q[l].x<=q[r].x)
			(q[l].v<=m?upd(q[l].y,q[l].v),tmp.pb(mp(q[l].y,q[l].v)),1:0),++l;
		if(q[r].v>m)ans[q[r].v-m]+=ask(q[r].y);
	}
	for(pii i:tmp)upd(i.fi,-i.se);
}
inline void UesugiErii(){
	int tot;cin>>n>>m>>(s+1);tot=m;
	for(int i=1,t;i<=n;i++)if(s[i]=='1'){
		for(t=i;s[t]=='1';++t);
		w.insert(mp(i,t)),i=t;
	}
	q.pb(node{});
	for(int i=1;i<=m;i++){
		string op;int x,y;cin>>op>>x;
		if(op=="toggle"){
			if(s[x]=='1'){
				auto it=w.upper_bound(mp(x,inf));--it;
				int l=(*it).fi,r=(*it).se;
				q.pb(node{l,x+1,i}),q.pb(node{l,r+1,-i}),
				q.pb(node{x+1,x+1,-i}),q.pb(node{x+1,r+1,i});
				assert(r>x);
				w.insert(mp(l,x)),w.insert(mp(x+1,r)),w.erase(it);
			}else{
				auto pre=w.upper_bound(mp(x,inf)),suf=w.upper_bound(mp(x,inf));int l=x,r=x+1;
				if(pre!=w.begin()&&(*--pre).se==x)l=(*pre).fi,w.erase(pre);
				if(suf!=w.end()&&(*suf).fi==x+1)r=(*suf).se,w.erase(suf);
				q.pb(node{l,x+1,-i}),q.pb(node{l,r+1,i}),
				q.pb(node{x+1,x+1,i}),q.pb(node{x+1,r+1,-i});
				w.insert(mp(l,r));
			}
			s[x]=(s[x]=='1'?'0':'1');
		}else{
			cin>>y,q.pb(node{x,y,++tot});
			auto l=w.upper_bound(mp(x,inf)),r=w.upper_bound(mp(y,inf));
			if(l==w.begin()||r==w.begin())continue;--l,--r;
			if((*l).se<x||(*r).se<y)continue;
			if(l==r)ans[tot-m]+=i;
		}
	}
	cdq(1,q.size()-1);
	for(int i=1;i<=tot-m;i++)cout<<ans[i]<<'\n';
}
signed main(){
	//IO();
	cfast;
	int _=1;//cin>>_;
	for(;_;_--)UesugiErii();
	return 0;
}
posted @ 2025-12-02 15:11  Uesugi1  阅读(1)  评论(0)    收藏  举报