HDU 4391 Paint the Wall (블록 체인 리스트 | 세그먼트 해시)
제목:
n 개의 점 이 있 습 니 다. 각 점 마다 하나의 색 (같 을 수 있 습 니 다) 이 있 습 니 다. 두 가지 조작: 1. 구간 [a, b] 을 색 c 로 염색 합 니 다.2. 구간 [a, b] 에서 색상 이 c 인 점 이 몇 개 있 는 지 물 어 봅 니 다.
문제 풀이 방향:
색상 의 종류 (5 개 이내) 가 적 으 면 클래식 한 선분 수 구간 염색 의 입문 문제 다.
그러나 이 문 제 는 색깔 이 너무 많아 하 쉬 를 진행 할 수 있 지만 규 모 는 10 ^ 5 에 달 할 수 있어 소박 하 게 선분 수 로 는 이 루어 질 수 없다.
근 데 다 들 선분 트 리 에 최적화 한 게 많아 요.(유지 구간 색상 종류의 최소 값 과 최대 값 을 조회 할 때 최적화 할 수 있 습 니 다)
그러나 믿 을 만 한 사 고 는 블록 체인 시트 로 문 제 를 세그먼트 하 쉬 라 고 한다.
사고방식: 각 블록 마다 맵 < color, cnt > 를 유지 합 니 다.
그 다음 에 업데이트 작업 에서 건 너 간 블록 에 대해 해당 하 는 map 를 비우 고 새로운 색상 을 추가 합 니 다. 길 이 는 Block 입 니 다.len, 대응 하 는 단일 색상 을 업데이트 하지 않 아 도 됩 니 다.
양 끝 이 한 덩어리 도 안 되 는 부분 에 대해 서 는 다양한 색상 이 나 올 수 있 으 므 로 한 점 의 색상 을 폭력 적 으로 업데이트 해 야 한다.
사실은 전체적인 사상 은 전체적인 색채 가 유일한 것 이 아니 라 한 점 의 가치 가 진실 치 에 대응 해 야 한 다 는 것 이다.이렇게 하면 어떤 블록 을 업데이트 할 때 O (1) 임 을 보증 할 수 있다.못 알 아 보 겠 으 면 코드 를 보 세 요...
처음에는 시간 을 초과 할 까 봐 맵 으로 이 루어 지지 못 했 지만 나중에 맵 을 대담 하 게 사용 하 라 는 말 을 듣 고 하 나 를 썼 습 니 다. 마침내 2 시간 동안 바 뀌 었 습 니 다. 마지막 블록 을 수정 할 때 아래 표 시 는 n 을 초과 하지 않도록 주의 하 세 요.
#include <map>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <algorithm>
using namespace std;
#define size(v) (int)v.size()
const int N = 1e5 + 5;
int n,color,a[N],block_len;
map<int,int> blocks_colors[333];
void bf_update(int l,int r)
{
int block_id = l / block_len;
if(size(blocks_colors[block_id]) == 1)
{
map<int,int>::iterator it = blocks_colors[block_id].begin();
int old_color = it->first;
int old_cnt = it->second;
if(color == old_color)
return ;
if(r - l + 1 == old_cnt)
{
blocks_colors[block_id][color] = r - l + 1;
blocks_colors[block_id].erase(it);
return ;
}
for(int i=block_len*block_id;i<n && i<block_len*(block_id+1);i++)
{
if(i >= l && i <= r)
a[i] = color;
else
a[i] = old_color;
}
blocks_colors[block_id][color] = r - l + 1;
blocks_colors[block_id][old_color] = old_cnt - (r - l + 1);
}
else
{
for(int i=l;i<=r;i++)
{
if(a[i] == color)
continue;
map<int,int>::iterator it = blocks_colors[block_id].find(a[i]);
if(it->second == 1)
blocks_colors[block_id].erase(it);
else
it->second--;
blocks_colors[block_id][color]++;
a[i] = color;
}
}
}
int bf_query(int l,int r)
{
int block_id = l / block_len;
if(blocks_colors[block_id].count(color))
{
if(size(blocks_colors[block_id]) == 1)
return r - l + 1;
else
{
int ret = 0;
for(int i=l;i<=r;i++)
if(a[i] == color)
++ret;
return ret;
}
}
else
return 0;
}
void update(int l,int r)
{
int block_id1 = l / block_len;
int block_id2 = r / block_len;
if(block_id1 == block_id2)
{
bf_update(l,r);
return ;
}
int rr = block_len * (block_id1 + 1) - 1;
int ll = block_len * block_id2;
bf_update(l,rr);
bf_update(ll,r);
for(int id=block_id1+1;id<block_id2;id++)
{
blocks_colors[id].clear();
blocks_colors[id][color] = block_len;
}
}
int query(int l,int r)
{
int block_id1 = l / block_len;
int block_id2 = r / block_len;
if(block_id1 == block_id2)
return bf_query(l,r);
int rr = block_len * (block_id1 + 1) - 1;
int ll = block_len * block_id2;
int ret = bf_query(l,rr) + bf_query(ll,r);
for(int id=block_id1+1;id<block_id2;id++)
if(blocks_colors[id].count(color))
ret += blocks_colors[id][color];
return ret;
}
void debug(int n,int max_id)
{
printf("color of a[]: ");
for(int i=0;i<n;i++)
printf("%d ",a[i]);
puts("***");
for(int i=0;i<=max_id;i++)
{
printf("the %dth block[%d,%d]=>
",i,i*block_len,(i+1)*block_len-1);
for(map<int,int>::iterator it=blocks_colors[i].begin();it!=blocks_colors[i].end();it++)
printf("\t\t\t %d -> %d
",it->first,it->second);
puts("");
}
}
int main()
{
//freopen("in.ads","r",stdin);
int m;
while(~scanf("%d%d",&n,&m))
{
block_len = (int)sqrt(n * 1.0);
//block_len = 400;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int block_id_max = n / block_len;
for(int i=0;i<=block_id_max;i++)
blocks_colors[i].clear();
for(int i=0;i<n;i++)
{
int block_id = i / block_len;
blocks_colors[block_id][ a[i] ]++;
}
int op,l,r;
while(m--)
{
scanf("%d%d%d%d",&op,&l,&r,&color);
if(op == 1)
update(l,r);
else
printf("%d
",query(l,r));
}
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.