【2020.5.23Code+】【JZOJ 6649】教科书般的亵渎

题目

Description
在这里插入图片描述

Input
如题

Output
如题

Sample Input
10 10
2 7 9
1 6
2 7 10
1 10
1 7
2 7 10
1 7
1 1
2 6 7
1 4

Sample Output
3
8
11
6

Data Constraint
在这里插入图片描述

思路

使用区间树维护形如(ji-i,ji]的区间,每次操作1,将包含 的区间从区间树上删除,相应地更新涉及的 。 使用树状数组维护ai的区间和,每删除一个区间均摊导致一次 的修改。 对答案有影响的区间只有nlogn个

代码

#include<bits/stdc++.h>
#define N 100010
#define M 1000010
#define ll long long
#define inf 0x7f7f7f7f
using namespace std; 
int n,m; 
struct per
{
	bool ty; 
	int x,y; 
} o[M]; 
int mn[N*4]; 
void ins(int k,int l,int r,int x,int c)
{
	mn[k]=min(mn[k],c); 
	if(l==r) return; 
	int mid=l+r>>1; 
	if(x<=mid) ins(k<<1,l,mid,x,c); 
	else ins(k<<1|1,mid+1,r,x,c); 
}
int query(int k,int l,int r,int st,int en)
{
	if(st<=l&&r<=en) return mn[k]; 
	int mid=l+r>>1,res=inf; 
	if(st<=mid)	res=min(res,query(k<<1,l,mid,st,en)); 
	if(mid<en) res=min(res,query(k<<1|1,mid+1,r,st,en)); 
	return res; 
}
int id[N]; 
struct per2
{
	int d,x,t; 
} q[N*20]; 
int cnt; 
bool cmpq(per2 a,per2 b){return a.t<b.t; }
bool f[N*20]; 
int ans[N]; 
ll t[N]; 
void add(int x,int c)
{
	for(; x<=n; x+=x&-x) t[x]+=c; 
}
ll qsum(int x){
	ll r=0; 
	for(; x; x-=x&-x)
		r+=t[x]; 
	return r; 
}
int main(){
	scanf("%d%d",&n,&m); 
	memset(mn,127,sizeof mn); 
	for(int i=1; i<=m; ++i){
		int ty; 
		scanf("%d",&ty); 
		if(ty==1){
			scanf("%d",&o[i].x),o[i].ty=0; 
			ins(1,1,n,o[i].x,i); 
		}
		else
			scanf("%d%d",&o[i].x,&o[i].y),o[i].ty=1; 
	}
	for(int i=1; i<=n; ++i)
		id[i]=(n-1)/i+1; 
	for(int i=1; i<=n; ++i)
		id[i]+=id[i-1]; 
	for(int i=1; i<=n; ++i)
		for(int j=0; j*i+1<=n; ++j)
			q[++cnt]={i,j,query(1,1,n,j*i+1,min(j*i+i,n))}; 
	sort(q+1,q+cnt+1,cmpq); 
	for(int i=1,j=1; i<=m; ++i)
	{
		for(; j<=cnt&&q[j].t<=i; ++j)
		{
			int d=q[j].d; 
			f[id[d-1]+1+q[j].x]=1; 
			int tmp=ans[d]; 
			while(id[d-1]+1+tmp<=id[d]&&f[id[d-1]+1+tmp])
				tmp++; 
			if(tmp!=ans[d]){
				add(d,tmp-ans[d]); 
				ans[d]=tmp; 
			}
		}
		if(o[i].ty==1)
			printf("%lld\n",qsum(o[i].y)-qsum(o[i].x-1)+o[i].y-o[i].x+1); 
	}
	return 0; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值