最后一个点本地跑出来 6.4s,卡不动了。
如果有更优的实现方法也行,我不嫌弃打大补丁。
#include <bits/stdc++.h>
#define ll long long
#define wr(x,ch) write(x),putchar(ch)
using namespace std;
const int SZ=1<<20;
char buf[SZ],*p1,*p2;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,SZ,stdin),p1==p2)?EOF:*p1++)
ll read(){
ll n=0; bool m=0;
char c=gc();
while(c<'0'||c>'9')m=c=='-',c=gc();
while(c>='0'&&c<='9')n=(n<<3)+(n<<1)+(c^'0'),c=gc();
return m?-n:n;
}
void write(ll x) {
if(x<0) putchar('-'),x=-x;
if(x>=10) write(x/10);
putchar(x%10^48);
return ;
}
const int N=500005,S=2500;
struct query {
int op,l,r,v;
}p[N];int n,m,q,s,bls,idx[N],L[N],R[N];
int cnt,top;ll ans[N];
struct rg {
int l,r,v,id;
}sta[N<<2];int lst[N<<2],nxt[N<<2];
struct Block1 {
ll sum1[N],sum2[N];
int idx[N],s,bls,L[N],R[N];
inline void add(int x,ll y) {
sum1[x]+=y,sum2[idx[x]]+=y;
return ;
}
ll ask(int l,int r) {
ll ans=0;
if(idx[l]==idx[r]) for(int i=l;i<=r;i++) ans+=sum1[i];
else {
for(int i=l;i<=R[idx[l]];i++) ans+=sum1[i];
for(int i=idx[l]+1;i<idx[r];i++) ans+=sum2[i];
for(int i=L[idx[r]];i<=r;i++) ans+=sum1[i];
}
return ans;
}
void init(int n) {
s=sqrt(n*2/3),bls=(n+s-1)/s;
for(int i=1;i<=bls;i++) {
L[i]=R[i-1]+1,R[i]=min(n,s*i);
for(int j=L[i];j<=R[i];j++) idx[j]=i;
}
return ;
}
}B1;
int tim;
struct Block2 {
ll sum1[N],sum2[1005],sum3[N],sum4[1005],idx[N],bls,s,L[N],R[N];
void init(int n) {
s=sqrt(n),bls=(n+s-1)/s;
for(int i=1;i<=bls;i++) {
L[i]=R[i-1]+1,R[i]=min(1ll*n,s*i);
for(int j=L[i];j<=R[i];j++) idx[j]=i;
}
return ;
}
void add(int x,ll y) {
tim++;
ll tmp=1ll*y*cnt;
for(int i=x;i<=R[idx[x]];i++) sum1[i]+=y,sum3[i]+=tmp;
for(int i=idx[x];i<=bls;i++) sum2[i]+=y,sum4[i]+=tmp;
return ;
}
inline ll ask(int l,int r) {
// tim++;
// return 0;
return 1ll*(ask2(r)-ask2(l-1))*cnt-(ask3(r)-ask3(l-1));
}
inline ll ask2(int x) {
return sum1[x]+sum2[idx[x]-1];
}
inline ll ask3(int x) {
return sum3[x]+sum4[idx[x]-1];
}
void clear() {
// tim++;
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
memset(sum3,0,sizeof(sum3));
memset(sum4,0,sizeof(sum4));
return ;
}
}B2;
struct node {
int id,v;
bool operator!=(const node &x) const {
return id!=x.id||v!=x.v;
}
}tag[N],a[N],non;vector<node> vec[N];
void func(int &l,int &r,int &v,int &id) {
if(l>r) return ;
for(int i=nxt[0];i;i=nxt[i]) {
int &pl=sta[i].l,&pr=sta[i].r,v=sta[i].v,id=sta[i].id;
if(l>pr||r<pl) continue;
B2.add(id,-1ll*(min(r,pr)-max(l,pl)+1)*v);
if(l<=pl&&pr<=r)
lst[nxt[i]]=lst[i],nxt[lst[i]]=nxt[i];
else {
if(pl<l&&r<pr) {
int t=++top;
sta[top]=(rg){r+1,pr,sta[i].v,sta[i].id};
lst[nxt[i]]=t;
nxt[t]=nxt[i],nxt[i]=t,lst[t]=i;
pr=l-1;
}else if(l<=pl) {
pl=r+1;
}else {
pr=l-1;
}
}
}
int t=++top;
sta[top]=(rg){l,r,v,id};
B2.add(id,1ll*v*(r-l+1));
nxt[t]=nxt[0];
lst[t]=0,lst[nxt[0]]=t,nxt[0]=t;
return ;
}
void pushdown(int x) {
if(tag[x]!=non) {
for(int i=L[x];i<=R[x];i++) a[i]=tag[x];
tag[x]=non;
return ;
}
return ;
}
signed main() {
// freopen("mfsn19.in","r",stdin);
// freopen("mfsn19.ans","w",stdout);
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
non=(node){-1,-1};
n=read(),m=read(),q=read();
B1.init(m),B2.init(m);
s=3000,bls=(n+s-1)/s;
for(int i=1;i<=bls;i++) {
L[i]=R[i-1]+1,R[i]=min(n,s*i);
tag[i]=non;
for(int j=L[i];j<=R[i];j++) idx[j]=i;
}
for(int i=1;i<=m;i++) {
p[i].op=read(),p[i].l=read(),p[i].r=read();
if(p[i].op==1) p[i].v=read();
}
for(int i=1;i<=q;i++) {
int l=read(),r=read();
vec[r].push_back((node){i,l});
}
for(int i=1;i<=m;i++) {
if(p[i].op==1) {
pushdown(idx[p[i].l]),pushdown(idx[p[i].r]);
if(idx[p[i].l]==idx[p[i].r])
for(int j=p[i].l;j<=p[i].r;j++) a[j]=(node){i,p[i].v};
else {
for(int j=p[i].l;j<=R[idx[p[i].l]];j++) a[j]=(node){i,p[i].v};
for(int j=idx[p[i].l]+1;j<idx[p[i].r];j++) tag[j]=(node){i,p[i].v};
for(int j=L[idx[p[i].r]];j<=p[i].r;j++) a[j]=(node){i,p[i].v};
}
}else {
if(idx[p[i].l]==idx[p[i].r]) {
if(tag[idx[p[i].l]]!=non) B1.add(tag[idx[p[i].l]].id,1ll*tag[idx[p[i].l]].v*(p[i].r-p[i].l+1));
else for(int j=p[i].l;j<=p[i].r;j++) B1.add(a[j].id,a[j].v);
}else {
if(tag[idx[p[i].l]]!=non) B1.add(tag[idx[p[i].l]].id,1ll*tag[idx[p[i].l]].v*(R[idx[p[i].l]]-p[i].l+1));
else for(int j=p[i].l;j<=R[idx[p[i].l]];j++) B1.add(a[j].id,a[j].v);
if(tag[idx[p[i].r]]!=non) B1.add(tag[idx[p[i].r]].id,1ll*tag[idx[p[i].r]].v*(p[i].r-L[idx[p[i].r]]+1));
else for(int j=L[idx[p[i].r]];j<=p[i].r;j++) B1.add(a[j].id,a[j].v);
for(int j=idx[p[i].l]+1;j<idx[p[i].r];j++) if(tag[j]!=non) B1.add(tag[j].id,1ll*tag[j].v*(R[j]-L[j]+1));
}
}
for(const auto &lxl:vec[i])
ans[lxl.id]=B1.ask(lxl.v,i);
}
cerr<<"cyy"<<"\n";
for(int i=1;i<=n;i++) a[i]=(node){0,0};
int zero=0;
for(int cyy=1;cyy<=bls;cyy++) {
int L=::L[cyy],R=::R[cyy];
cnt=0;
sta[top=1]=(rg){L,R,0,0};
lst[1]=nxt[1]=0,nxt[0]=lst[0]=1;
B2.clear();
node tag=non;
for(int i=1;i<=m;i++) {
int il=idx[p[i].l],ir=idx[p[i].r];
if(p[i].op==1) {
if(il<cyy&&cyy<ir) func(L,R,zero,zero),tag=(node){i,p[i].v};
else if(!(p[i].l>R||p[i].r<L)) {
if(tag!=non) {
func(L,R,tag.v,tag.id);
tag=non;
}
int pl=max(L,p[i].l),pr=min(R,p[i].r);
func(pl,pr,p[i].v,i);
}
}else if(p[i].op==2) {
if(il<cyy&&cyy<ir) cnt++;
}
for(const auto &lxl:vec[i])
ans[lxl.id]+=B2.ask(lxl.v,i);
}
}
cerr<<tim<<"\n";
for(int i=1;i<=q;i++) wr(ans[i],'\n');
return 0;
}