제목 설명
기술
입력
출력
출력 선 (Q)은, i 번째 행 데이터 디 않음을 나타낸다.
입력 샘플
4 3 2
1 1 2 4
2 1 2
1 1 5 3
2 2 3
예제 출력
0
4
14
22
데이터 제약
문제 해결
분명히 CDQ + 트리 라인 플러스는 각 작업의 기여도를 계산
심문은 변경에 따라 후 메시지 따라하기 전에, 변경 사항이
그러나 세그먼트 트리 펜윅 나무와 어떤 차이 T, 그렇게 될 것입니다
로 표현 두 개방 펜윅 나무, 심문 1 ~ 추가 S2 s의에서 t의 S1 + S2의 *의 t, 저장 S1 (t-1)에서 *의 t에서 t 수정,
암호
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define low(x) (x&-(x))
using namespace std;
struct type{
int type,l,r,s,t,id;
} a[200001];
long long ans[200001];
long long tr[200001];
long long Tr[200001]; //*t
bool bz[200001];
int d[200001];
int n,Q,i,j,k,l,t,len;
bool cmp(type a,type b)
{
return a.t<b.t;
}
bool Cmp(type a,type b)
{
return a.id<b.id;
}
void Change(int t,int s)
{
long long S=(long long)(t-1)*s;
while (t<=n)
{
tr[t]-=S;
Tr[t]+=s;
if (!bz[t])
bz[t]=1,d[++len]=t;
t+=low(t);
}
}
void change(int l,int r,int s)
{
Change(l,s);
Change(r+1,-s);
}
long long Find(int t)
{
long long T=t,ans=0,s=0;
while (t)
{
ans+=tr[t];
s+=Tr[t];
t-=low(t);
}
return ans+s*T;
}
long long find(int l,int r)
{
return Find(r)-Find(l-1);
}
void clear()
{
int i;
fo(i,1,len)
tr[d[i]]=0,Tr[d[i]]=0,bz[d[i]]=0;
len=0;
}
void work(int L,int R)
{
int i,Mid=(L+R)/2;
if (L==R) return;
work(L,Mid);
work(Mid+1,R);
sort(a+L,a+R+1,Cmp);
fo(i,L,R)
if (a[i].t<=Mid && a[i].type==1)
change(a[i].l,a[i].r,a[i].s);
else
if (a[i].t>Mid && a[i].type==2)
ans[a[i].t]+=find(a[i].l,a[i].r);
clear();
fd(i,R,L)
if (a[i].t<=Mid && a[i].type==2)
change(a[i].l,a[i].r,1);
else
if (a[i].t>Mid && a[i].type==1)
ans[a[i].t]+=find(a[i].l,a[i].r)*a[i].s;
clear();
}
int main()
{
freopen("generator.in","r",stdin);
freopen("generator.out","w",stdout);
scanf("%d%d",&n,&Q);
fo(i,1,Q-1)
{
scanf("%d",&j);
a[j].t=i;
}
fo(i,1,Q)
{
scanf("%d",&a[i].type);
if (a[i].type==1)
scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].s);
else
scanf("%d%d",&a[i].l,&a[i].r);
a[i].id=i;
++a[i].t;
}
sort(a+1,a+Q+1,cmp);
work(1,Q);
fo(i,1,Q)
{
ans[i]+=ans[i-1];
printf("%lld\n",ans[i]);
}
fclose(stdin);
fclose(stdout);
return 0;
}