hdu 1166 적병 포진(라인 트리)
4873 단어 세그먼트 트리
2. 두 갈래 나무의 깊이를 h로 설정하면 h층을 제외한 다른 각 층(1~h-1)의 결점은 최대 개수에 달하고 h층의 모든 결점은 연속적으로 맨 왼쪽에 집중된다. 이것이 바로 완전 두 갈래 나무다.완전 두 갈래 나무는 두 갈래 나무로 가득 차서 끌어낸 것이다.깊이가 K인 경우 N개의 결점이 있는 두 갈래 나무는 각 결점이 깊이가 K인 만 두 갈래 나무의 번호가 1부터 n까지의 결점과 일일이 대응할 때만 완전 두 갈래 나무라고 부른다.만약에 두 갈래 나무가 가장 아래의 두 층의 결점만 있는 도수가 2보다 작고 가장 아래층의 결점이 모두 이 층의 가장 왼쪽의 몇몇 위치에 집중된다면 이 두 갈래 나무는 완전한 두 갈래 나무가 된다.
적군이 포진하다.
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 52472 Accepted Submission(s): 21982
Problem Description
C국의 라이벌 A국은 그동안 군사훈련을 하고 있었기 때문에 C국의 스파이 두목 데릭과 그의 부하 티디는 또 바쁘게 움직이기 시작했다.A국은 해안선을 따라 직선으로 N개의 공병 캠프를 배치했는데 데릭과 티디의 임무는 이 공병 캠프의 활동 상황을 감시하는 것이다.어떤 선진적인 모니터링 수단을 채택했기 때문에 모든 공병 캠프의 인원수는 C국이 모두 파악하고 있다. 모든 공병 캠프의 인원수는 변동이 발생할 수 있고 약간의 인원을 증가하거나 줄일 수 있지만 이런 것들은 모두 C국의 감시를 피할 수 없다.
중앙정보국은 적들이 도대체 어떤 전술을 훈련하는지 연구해야 하기 때문에 티디는 수시로 데릭에게 어떤 연속된 공병 캠프가 모두 몇 명인지 보고해야 한다. 예를 들어 데릭은 "티디, 당장 세 번째 캠프부터 열 번째 캠프까지 모두 몇 명인지 보고해라!"라고 물었다.Tidy는 곧 이 단락의 총 인원수를 계산하여 보고할 것이다.그러나 적병 캠프의 인원수는 자주 변동한다. 데릭은 매번 묻는 단락이 다르기 때문에 티디는 매번 한 캠프씩 가서 세어야 한다. 곧 기진맥진한다. 데릭은 티디의 계산 속도에 대해 점점 불만스러워한다. "너 뚱뚱한 놈아, 이렇게 느리게 계산하면 해고해!"라고 티디는 생각했다. "너 혼자 계산해 봐. 이건 정말 힘든 일이야! 난 네가 나를 해고하는 게 미워!"어쩔 수 없이 Tidy는 컴퓨터 전문가인 Windbreaker에게 전화를 걸어 구조를 요청했다. Windbreaker는 말했다. "뚱뚱한 녀석, 평소에 acm 문제를 많이 풀고 알고리즘 책을 많이 보라고 했는데 이제 고과를 맛보겠지!"Tidy: "잘못 알았어..."하지만 윈드브레이크는 전화를 끊었습니다.Tidy는 매우 고민한다. 이렇게 하면 그는 정말 붕괴될 것이다. 똑똑한 독자, 너는 프로그램을 써서 그를 도와 이 일을 완성할 수 있니?그러나 만약 당신의 프로그램 효율이 높지 않다면, Tidy는 여전히 Derek의 꾸지람을 받을 것이다.
Input
첫 번째 줄에는 T 그룹 데이터가 있음을 나타내는 정수 T가 있습니다.
각 조의 데이터 첫 줄에 하나의 정수 N(N<=50000)은 적에게 N개의 공병 캠프가 있음을 나타낸다. 그 다음에 N개의 정수가 있고 i번째 정수 ai는 i번째 공병 캠프가 시작될 때ai개인(1<=ai<=50)을 대표한다.
다음 줄마다 하나의 명령이 있고 명령은 네 가지 형식이 있다.
(1) Add i j, i와 j는 정수로 제 캠프의 j 개인 증가를 나타낸다(j는 30을 초과하지 않는다)
(2) Sub ij, i와 j는 정수로 제 i캠프가 j개인을 줄인다는 것을 나타낸다(j는 30을 초과하지 않는다).
(3)Query ij, i와 j는 정수이고 i<=j는 제이에서 제이 캠프까지의 총 인원수를 묻는다.
(4) End는 종료를 나타내며 이 명령은 각 그룹의 데이터 마지막에 나타납니다.
그룹당 최대 40000개의 명령
Output
i그룹 데이터에 대해 먼저 "Case i:"및 리턴을 출력하고
모든 Query 질문에 대해 정수를 출력하고 리턴합니다. 질문한 단락의 총 인원수를 나타냅니다. 이 숫자는 int 안에 유지됩니다.
Sample Input
1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
Sample Output
Case 1:
6
33
59
코드:#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int l,r,x;
node(){}
node(int a,int b,int c):l(a),r(b),x(c){}
};
node a[400000];//
int ans;
void build(int l,int r,int i)
{
a[i]=node(l,r,0);
if(l==r)
return;
int mid=(l+r)/2;
build(l,mid,2*i);
build(mid+1,r,2*i+1);
}
void update(int p,int add,int i)//
{
if(a[i].l==a[i].r&&a[i].r==p)
{
a[i].x+=add;
return;
}
//
int mid=(a[i].l+a[i].r)/2;
if(p<=mid)
update(p,add,2*i);
else
update(p,add,2*i+1);
//
/*update(p,add,2*i);
update(p,add,2*i+1);*/
a[i].x=a[2*i].x+a[2*i+1].x;//
}
void query(int l,int r,int i)
{
if(a[i].l==l&&a[i].r==r)
{
ans+=a[i].x;
return;
}
int mid=(a[i].l+a[i].r)/2;
if(r<=mid)
query(l,r,2*i);
else if(l>=mid+1)
query(l,r,2*i+1);
else
{
query(l,mid,2*i);
query(mid+1,r,2*i+1);
}
}
int main()
{
int t;
int n;
int x;
char str[10];
scanf("%d",&t);
for(int k=1;k<=t;k++)
{
scanf("%d",&n);
build(1,n,1);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
update(i,x,1);
}
printf("Case %d:
",k);
while(scanf("%s",str)&&strcmp("End",str)!=0)
{
if(strcmp("Add",str)==0)
{
int i;
scanf("%d%d",&i,&x);
update(i,x,1);
}
if(strcmp("Sub",str)==0)
{
int i;
scanf("%d%d",&i,&x);
update(i,-x,1);
}
if(strcmp("Query",str)==0)
{
int l,r;
ans=0;
scanf("%d%d",&l,&r);
query(l,r,1);
printf("%d
",ans);
}
}
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
백준 알고리즘 14427번 : 수열과 쿼리 15
길이가 N인 수열 A1, A2, ..., AN이 주어진다.
이때, 다음 쿼리를 수행하는 프로그램을 작성하시오.
1 i v : Ai를 v로 바꾼다.
(1 ≤ i ≤ N, 1 ≤ v ≤ 109)
2 : 수열에서 크기가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
Case 1:
6
33
59
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int l,r,x;
node(){}
node(int a,int b,int c):l(a),r(b),x(c){}
};
node a[400000];//
int ans;
void build(int l,int r,int i)
{
a[i]=node(l,r,0);
if(l==r)
return;
int mid=(l+r)/2;
build(l,mid,2*i);
build(mid+1,r,2*i+1);
}
void update(int p,int add,int i)//
{
if(a[i].l==a[i].r&&a[i].r==p)
{
a[i].x+=add;
return;
}
//
int mid=(a[i].l+a[i].r)/2;
if(p<=mid)
update(p,add,2*i);
else
update(p,add,2*i+1);
//
/*update(p,add,2*i);
update(p,add,2*i+1);*/
a[i].x=a[2*i].x+a[2*i+1].x;//
}
void query(int l,int r,int i)
{
if(a[i].l==l&&a[i].r==r)
{
ans+=a[i].x;
return;
}
int mid=(a[i].l+a[i].r)/2;
if(r<=mid)
query(l,r,2*i);
else if(l>=mid+1)
query(l,r,2*i+1);
else
{
query(l,mid,2*i);
query(mid+1,r,2*i+1);
}
}
int main()
{
int t;
int n;
int x;
char str[10];
scanf("%d",&t);
for(int k=1;k<=t;k++)
{
scanf("%d",&n);
build(1,n,1);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
update(i,x,1);
}
printf("Case %d:
",k);
while(scanf("%s",str)&&strcmp("End",str)!=0)
{
if(strcmp("Add",str)==0)
{
int i;
scanf("%d%d",&i,&x);
update(i,x,1);
}
if(strcmp("Sub",str)==0)
{
int i;
scanf("%d%d",&i,&x);
update(i,-x,1);
}
if(strcmp("Query",str)==0)
{
int l,r;
ans=0;
scanf("%d%d",&l,&r);
query(l,r,1);
printf("%d
",ans);
}
}
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
백준 알고리즘 14427번 : 수열과 쿼리 15길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v : Ai를 v로 바꾼다. (1 ≤ i ≤ N, 1 ≤ v ≤ 109) 2 : 수열에서 크기가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.