Riva 12436 Rip Van Winkle 's Code (구간 업데이트, 구간 조회)
조작 A 와 조작 B 는 모두 조작 한 것 이 고 실제로는 등차 수열 이기 때문에 함께 고려 할 수 있다.아니면 선분 트 리 입 니까? AB 를 조작 할 때 온라인 트 리 의 결산 점 에 왼쪽 점 에 추가 할 값 add 1, 오른쪽 점 에 추가 할 값 add 2 를 기록 하고 이 구간 의 공차 step (모두 AB 를 조작 하 는 게 으 른 작업 표시) 를 기록 합 니 다.C 를 조작 하 는 데 있어 서 온라인 트 리 의 결산 점 에 서 는 하나의 flag 로 현재 구간 내의 수가 모두 같 는 지 를 표시 하고, 구간 안의 수가 완전히 같 을 때, 즉 flag = 1 일 때 이 수 는 얼마 인지 (모두 C 를 조작 하 는 게 으 른 작업 표시) 를 valu 로 표시 합 니 다.
쉽게 얻 을 수 있 으 며 등차 수열 을 더 할 지 등차 수열 을 더 할 지 한 구간 에 대해 여러 차례 AB 조작 을 할 수 있다.C 작업 에 대해 서 는 구간 내 할당 값 을 x 로 강제 하기 때문에 이전의 AB 작업 은 모두 실 효 됩 니 다. 즉, 이때 AB 작업 을 나타 내 는 몇 개의 변 수 를 add 1, add 2 와 step 의 모든 할당 값 을 0 으로 해 야 합 니 다.하위 구간 에 기 록 된 값 을 전달 할 때 는 C 조작 표 시 를 우선 해 야 하 는데, AB 조작 과 C 조작 표시 가 동시에 존재 할 때 는 C 조작 을 먼저 하고 AB 조작 을 한 것 이 틀림 없고, 이때 AB 의 표 시 를 먼저 아래로 전달 하고 C 의 표 시 를 전달 하면 결과 가 부정 확 하 게 나 올 수 있 기 때문이다.
WA 오 랜 만 에 저 지 른 두 가지 실수:
1. 시작 할 때 add 1, add 2 만 기록 한 다음 에 하위 구간 에 게 으 른 작업 의 값 을 전달 합 니 다. 즉, add 1 과 add 2 를 전달 할 때 두 구간 으로 분해 하여 (add 1, mid 1), (mid 2, add 2) 로 설정 하고 (add1 + add 2) / 2 를 통 해 mid 1 을 직접 얻 은 다음 에 mid 2 는 점차 증가 하거나 점차 감소 하 는 것 에 따라 1 을 더 해 야 합 니 다. 실제로 여기에 공차 를 더 하거나 빼 야 합 니 다.선분 나무의 결점 에 공차 step 를 추가 한 이유 다.
2. 조작 C 의 표 시 는 valu 만 있 고 flag 가 없습니다. 잘못된 것 은 valu 값 이 0 이 아니라면 아래로 전달 할 값 이 있다 는 것 입 니 다. 실제로 조작 C 는 구간 의 모든 값 을 0 으로 할당 할 수 있 습 니 다. 이때 valu 는 0 이 고 아래로 전달 되 지 않 아 오류 가 발생 하지 않 습 니 다. 그래서 표 시 를 하나 더 추가 하 였 습 니 다.
PS: 어떤 OJ 에 서 는 * 2 가 좀 느 려 요.
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=250005;
typedef long long LL;
struct node
{
bool flag;
int left,right;
LL sum,add1,add2,valu,step;
LL mid(){return left+(right-left)/2;}
LL len(){return right-left+1;}
void changeAB(LL a,LL b,LL k)
{
add1+=a; add2+=b; step+=k;
sum+=(a+b)*len()/2;
}
void changeC(LL a)
{
flag=1; valu=a;
add1=0; add2=0; step=0;
sum=valu*len();
}
};
struct Segtree
{
node tree[N*4];
void down(int ind)
{
if(tree[ind].flag)
{
tree[ind*2].changeC(tree[ind].valu);
tree[ind*2+1].changeC(tree[ind].valu);
tree[ind].flag=0;
}
if(tree[ind].add1||tree[ind].add2||tree[ind].step)
{
LL add1=tree[ind].add1,add2=tree[ind].add2;
LL k=tree[ind].step;
LL mid=add1+k*(tree[ind*2].len()-1);
tree[ind*2].changeAB(add1,mid,k);
tree[ind*2+1].changeAB(mid+k,add2,k);
tree[ind].add1=0; tree[ind].add2=0;
tree[ind].step=0;
}
}
void build(LL left,LL right,LL ind)
{
tree[ind].left=left; tree[ind].right=right;
tree[ind].add1=0; tree[ind].add2=0;
tree[ind].sum=0; tree[ind].valu=0;
tree[ind].step=0;
if(left!=right)
{
LL mid=tree[ind].mid();
build(left,mid,ind*2);
build(mid+1,right,ind*2+1);
}
}
void updataAB(LL be,LL end,LL ind,LL step)
{
LL left=tree[ind].left,right=tree[ind].right;
if(be<=left&&right<=end)
{
LL st,ed;
if(step>=0) {st=left-be+1;ed=right-be+1;}
else {st=end-left+1;ed=end-right+1;}
tree[ind].changeAB(st,ed,step);
}
else
{
down(ind);
LL mid=tree[ind].mid();
if(be<=mid) updataAB(be,end,ind*2,step);
if(end>mid) updataAB(be,end,ind*2+1,step);
tree[ind].sum=tree[ind*2].sum+tree[ind*2+1].sum;
}
}
void updataC(LL be,LL end,LL ind,LL valu)
{
LL left=tree[ind].left,right=tree[ind].right;
if(be<=left&&right<=end) tree[ind].changeC(valu);
else
{
down(ind);
LL mid=tree[ind].mid();
if(be<=mid) updataC(be,end,ind*2,valu);
if(end>mid) updataC(be,end,ind*2+1,valu);
tree[ind].sum=tree[ind*2].sum+tree[ind*2+1].sum;
}
}
LL query(LL be,LL end,LL ind)
{
LL left=tree[ind].left,right=tree[ind].right;
if(be<=left&&right<=end) return tree[ind].sum;
else
{
down(ind);
LL mid=tree[ind].mid();
LL sum1=0,sum2=0;
if(be<=mid) sum1=query(be,end,ind*2);
if(end>mid) sum2=query(be,end,ind*2+1);
return sum1+sum2;
}
}
}seg;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
seg.build(1,N-5,1);
for(int i=0;i<n;i++)
{
char str[10];
LL a,b,c;
scanf("%s",str);
if(str[0]=='A')
{
scanf("%lld%lld",&a,&b);
seg.updataAB(a,b,1,1);
}
else if(str[0]=='B')
{
scanf("%lld%lld",&a,&b);
seg.updataAB(a,b,1,-1);
}
else if(str[0]=='C')
{
scanf("%lld%lld%lld",&a,&b,&c);
seg.updataC(a,b,1,c);
}
else
{
scanf("%lld%lld",&a,&b);
printf("%lld
",seg.query(a,b,1));
}
}
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 1부이 기사에서는 Entity Framework Core Code First 접근 방식을 사용하는 ASP.NET Core 6.0 WEP API의 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업에 대해 설명합니다. 웹 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.