poj 2352 Stars
사고: 나무 모양 배열 분석: 1 문 제 는 각 점 의 왼쪽 아래 (왼쪽 + 바로 아래) 에 몇 개의 별 이 있 는 지 요구 하 는 것 이다. 그 점 이 바로 몇 층 이 고 마지막 으로 0 ~ n - 1 층 의 점 을 출력 하 는 것 이다.예 를 들 어 견본 번호 가 5 인 별 은 왼쪽 아래 에 3 개의 별 이 있 으 면 5 는 3 층 2 에 있 고 나무 모양 의 배열 을 이용 합 니 다. 우 리 는 나무 모양 의 배열 C 에서 C [i] 는 원래 의 배열 A 중의 한 부분 과 합 을 나타 내 는 것 을 알 고 있 습 니 다.문 제 는 입력 할 때 Y 값 이 커지 는 순서 (y 는 똑 같이 x 가 커진다) 라 고 명확 하 게 지적 했다. 그러면 우 리 는 무엇 을 원래 의 배열 A 로 해 야 하 는 지, 바로 X 축 이 고 A [2] 는 x = 2 를 나타 내 는 점 의 개수 이다.그러면 한 점 의 x 값 이 2 일 때 A [2] +, 이때 C [2], C [2 + lowbit (2) 를 업데이트 해 야 합 니 다.
3. 어떤 점 의 왼쪽 아래 에 몇 개의 별 이 있 는 지 어떻게 구 할 수 있 습 니까? 분명히 왼쪽 아래 에 있 는 점 의 x 수 치 는 현재 점 보다 작 을 것 입 니 다. 그러면 나무 모양 의 배열 과 비슷 합 니 다. 그러면 전체 문제 의 방향 은 4. 나무 모양 의 배열 을 업데이트 할 때 x < = MAXN 에 주의 하 세 요. 입력 한 n 이 아 닙 니 다.A [x] 가 변경 되 었 기 때문에 C [x], C [x + lowbit (x)] 를 업데이트 해 야 합 니 다.
5 문제 가 입력 한 x 의 좌 표 는 0 일 수 있 기 때문에 여기 서 우 리 는 모든 x + 1 을 피 할 수 있 습 니 다. 그러면 TLE 를 피 할 수 있 습 니 다.
코드:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 32010;
int n , ans[MAXN];
int treeNum[MAXN];
int lowbit(int x){
return x&(-x);
}
int getSum(int x){
int sum = 0;
while(x){
sum += treeNum[x];
x -= lowbit(x);
}
return sum;
}
void add(int x , int val){
while(x < MAXN){
treeNum[x] += val;
x += lowbit(x);
}
}
int main(){
int x , y;
while(scanf("%d" , &n) != EOF){
memset(treeNum , 0 , sizeof(treeNum));
memset(ans , 0 , sizeof(ans));
for(int i = 0 ; i < n ; i++){
scanf("%d%d" , &x , &y);
x++;
ans[getSum(x)]++;
add(x , 1);
}
for(int i = 0 ; i < n ; i++)
printf("%d
" , ans[i]);
}
return 0;
}
사고방식: 라인 트 리 + 단점 업데이트 분석: 1 문제 가 입력 한 점 은 y 의 오름차 순 이 고 같은 y 는 x 의 오름차 순 이다.그러면 우 리 는 뒤에 입력 한 점 이 앞 점 의 왼쪽 아래 에 있 지 않다 는 것 을 알 수 있다. 그러면 우 리 는 고려 하기 만 하면 된다.이렇게 하면 1 차원 의 문제 가 되 어 선분 수 를 이용 하여 할 수 있다.2. 우 리 는 한 점 이 다른 점 의 왼쪽 아래 에 있다 는 것 을 알 고 있다. 그러면 이 점 의 x 수 치 는 틀림없이 다른 점 보다 작 을 것 이다.그러면 새로 가입 한 점 은 갱신 구간 [x, x] 과 같 습 니 다. 그리고 왼쪽 아래 에 몇 가지 점 을 요구 하 는 것 은 구간 [0, x] 의 합 입 니 다.3. 생각 을 알 게 되면 선분 수 를 이용 하여 구 할 수 있다.이 문 제 는 입력 데이터 가 질서 가 있 기 때문에 뒤의 것 은 앞의 것 에 영향 을 주지 않 습 니 다. 그러면 우 리 는 입력 한 후에 업데이트 하기 전에 이전의 level 을 구 할 수 있 습 니 다.이런 식 으로 모든 것 을 추구 하 다.4. x 값 이 0 일 수 있 으 므 로 루트 노드 구간 은 [0, MAXN] 입 니 다. 코드:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 32010
struct Node{
int left;
int right;
int sum;
};
Node node[4*MAXN];
int vis[MAXN];
/* */
void buildTree(int left , int right , int pos){
node[pos].left = left;
node[pos].right = right;
node[pos].sum = 0;
if(left == right)
return;
int mid = (left+right)>>1;
buildTree(left , mid , pos<<1);
buildTree(mid+1 , right , (pos<<1)+1);
}
/* */
void update(int index , int pos){
if(node[pos].left == node[pos].right){
node[pos].sum++;
return;
}
int mid = (node[pos].left+node[pos].right)>>1;
if(index <= mid)
update(index , pos<<1);
else
update(index , (pos<<1)+1);
node[pos].sum = node[pos<<1].sum + node[(pos<<1)+1].sum;
}
/* */
int query(int left , int right , int pos){
if(node[pos].left == left && node[pos].right == right)
return node[pos].sum;
int mid = (node[pos].left+node[pos].right)>>1;
if(right <= mid)
return query(left , right , pos<<1);
else if(left > mid)
return query(left , right , (pos<<1)+1);
else
return query(left , mid , pos<<1)+query(mid+1 , right , (pos<<1)+1);
}
int main(){
int Case , n;
int x , y;
scanf("%d" , &Case);
n = Case;
buildTree(0 , MAXN , 1);
memset(vis , 0 , sizeof(vis));
while(Case--){
scanf("%d%d" , &x , &y);
vis[query(0 , x , 1)]++;
update(x , 1);
}
for(int i = 0 ; i < n ; i++)
printf("%d
" , vis[i]);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.