題目連接
題意
- 就是開始有一個數組a,開始有∀i∈[1,n],ai=i,還有另一個數組b,開始有∀i∈[1,n],bi=0,初始化然後兩種操作,第一種操作是先對於∀i∈[l,r],令b[i]=b[i]+∣x−a[i]∣,然後將[l,r]內的所有a數組的數變成x,第二種操作查詢b數組的區間和
題解
- 神奇的分塊,對於a數組,每個塊打上標記表示這個塊內所有數是否都相同,然後對於b數組,打上標記表示這個塊所有位置的數都要加上多少,然後處理第一種操作的時候不完整的塊暴力處理,完整的塊裏面如果標記一相同,那麼O(1)更新數據,否則暴力修改所有b數組元素
- 複雜度O(能過)
代碼
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int smaxn=3005;
int n,m,opt,l,r,x;
namespace blocking{
int tot,belong[maxn],siz[smaxn],block;
long long a[maxn],same[smaxn],sum[smaxn],mark[smaxn],b[maxn];
inline void init(int n) {
block=(int)sqrt((double)n);
tot=n%block?(n/block+1):(n/block);
for(int i=1;i<=n;i++) belong[i]=(i-1)/block+1;
for(int i=1;i<=tot;i++) siz[i]=(min(i*block,n)-(i-1)*block);
}
inline void solve(int l,int r,long long val) {
for(int i=l;i<=r;i++) {
if(same[belong[i]]) {
for(int j=(belong[i]-1)*block+1;j<=belong[i]*block;j++) a[j]=same[belong[i]];
same[belong[i]]=0;
}
sum[belong[i]]+=abs(val-a[i]);
b[i]+=abs(val-a[i]);
a[i]=val;
}
}
inline void update(int l,int r,long long val) {
if(belong[r]-belong[l]<=1) {
solve(l,r,val);
return;
}
solve(l,belong[l]*block,val);
for(int i=belong[l]+1;i<=belong[r]-1;i++) {
if(!same[i]) solve((i-1)*block+1,i*block,val),same[i]=val;
else {
mark[i]+=abs(val-same[i]);
sum[i]+=1LL*block*abs(val-same[i]);
same[i]=val;
}
}
solve((belong[r]-1)*block+1,r,val);
}
inline long long query(int l,int r) {
long long ans=0;
if(belong[r]-belong[l]<=1) {
for(int i=l;i<=r;i++) ans+=b[i]+mark[belong[i]];
return ans;
}
for(int i=l;i<=belong[l]*block;i++) ans+=b[i]+mark[belong[i]];
for(int i=belong[l]+1;i<=belong[r]-1;i++) ans+=sum[i];
for(int i=(belong[r]-1)*block+1;i<=r;i++) ans+=b[i]+mark[belong[i]];
return ans;
}
inline void debug() {
printf("block= %d, tot= %d\n",block,tot);
for(int i=1;i<=n;i++) printf("%d%c",belong[i],i==n?'\n':' ');
}
}
using namespace blocking;
int main()
{
scanf("%d %d",&n,&m);init(n);
for(int i=1;i<=n;i++) a[i]=i;
for(int i=1;i<=m;i++) {
scanf("%d",&opt);
if(opt==1) {
scanf("%d %d %d",&l,&r,&x);
update(l,r,x);
}else {
scanf("%d %d",&l,&r);
printf("%lld\n",query(l,r));
}
}
}