题目
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;
}