주제 :
기차가 UOJ에 속하는 관리하는 데 사용 기차 정류장, 거기 UOJ.
N- 형의 총 훈련
N- 형
조각 1, ..., N- 형 번호가
1, ..., N- 형
단지로 인해 특별한 구조에 기차 레일의 한쪽 끝, 기차를 보유하는 데 사용, 각 철도 차량이 주차 할 수있는 수많은 작은 기차를. 각 철도는 서로 독립적입니다.
주차 된 기차가 먼저 나올 수 후 철도, 스택 구조입니다.
기차 당 톤수는 t의가
t을
.
NOI2016오고 있기 때문에, 당신은 하루에 많은 이벤트를 처리 할 수있는 작은 앞 사람을 싸우고, 기차역 관리자 아홉 개 가난한 필요로 훈련을합니다.
같은 사건의 약 3 종류의 요약 될 수있다 :
• 1 LR 누군가에 철도 번호에 원하는 [L, R]
[L, R]
작은 각 철도가 처음 기차 싸움에서 캔을 열어 긍정적, 당신은 이러한 통계를 훈련 할 필요가 톤수없이 철도 열차는 대답에 포함되지 않습니다.
• 2리터 번호 L의
L의
철도는 더 기차 밖으로하지 않는 경우 철도 기차를 몰았다.
[L, R]에서 • 3 LRX 철도 번호
[L, R]
각 철도는 X-의 새로운 공원 톤수있는
X 축에
기차.
이제 그를 위해 당신이 기차역을 관리하는 데 필요한, 남중국해의 최전선에 가서 아홉 가난한 관리자.
바쁜 기차역으로, 그래서 당신은 실시간 피드백이 필요합니다, 우리는 온라인으로 강제로 특정 입력 형식을 보려면 몇 가지 방법을 사용하도록 요구합니다.
입력 형식
첫 번째 행의 세 음이 아닌 정수 N-, m의 입력은 TY
N-, m은 TY는
동작 횟수 및 철도 및 필수 여부 개수를 나타낸다.
이어서 m에서
m의
세 개의 숫자 또는 네 개의 숫자 또는 숫자의 행은 하나의 동작을 나타낸다.
실시간 피드백 정보는 L, R & LT 해독 할 필요가
L, R & LT를
제공하는 판독 L1, R1
L1, R1
, 실제 값은 다음과 같다 :
==== L2r2lr (L1 + Lastans⋅ty) Modn + 1 (R1 + Lastans⋅ty) Modn + 볼 (L2, R2) 1 분 에서 최대 (L2, R2)
L2 = (L1 + Lastans⋅ty) Modn + 1R2 = ( R1 +의 lastans⋅ty) modn 1리터 + = 분 (L2, R2) R = 최대 (L2, R2)
lastans는
lastans
질의에 대한 답 한 번하지 않을 경우 요청하기 전에 또는 0, 표현
0
.
는 동작의 제 2 타입 있으므로 만 L = (L1 + lastans⋅ty) modN. 1 + 수행 할 때
L = (L1 + lastans⋅ty) modN +. (1)
에있다.
입력 데이터는 1≤l1, r1≤n 보장하기 위해
, r1≤n을 1≤l1을
.
우리는 톤수 및 운영의 유형을 암호화하지 않아도됩니다
출력 형식
질문의 각 출력 라인, 음이 아닌 정수의 답.
샘플
입력
10 10 0
3 1 5 3
1 1 6
3 1 7 1
1 1 9
1 1 6
3 5 2 1
1 3 6
1 3 9
3 1 7 6
2 1
출력
15
7
6
7
8
http://uoj.ac/problem/218
솔루션 :
우리는 시간에 나무의 지속 가능한 세그먼트를 구축 스택 열차의 각 레일 톤수 및 상단의 각 기간에 대한 스택의 스택 상단을 유지할 수 있습니다.
우리가 통계 대답 세그먼트 트리를 유지합시다.
그래서 단지 세에서 작동하는 다음
의 질문의 범위 : 직접 질문 세그먼트 트리에 대답 할 수 있습니다.
간격 압력 : 트리 라인 커버에 대한 섹션에서 지속적으로, 그리고 다음 응답 세그먼트 트리에서 변경.
단일 지점 폭탄의 수 : 우리는 스택 시간을 기록하기 때문에, 시간 t에 대한 인바운드 문의, 우리는 다음 트리 라인과 대답을, 시간 t 전에 나무를 조회 현재 시점 스택 전에 스택의 상단에 정보를 찾을 수 있습니다 지속성 트리 라인을 수정할 수 있습니다.
코드 :
#include<iostream>
#include<stdio.h>
#include<string.h>
#define N 500005
#define lson id*2
#define rson id*2+1
using namespace std;
int n,m,sum[N*4],lazy[N*4];
void pd(int id,int l,int r,int mid)
{
if(lazy[id]==-1) return ;
sum[lson]=(mid-l+1)*lazy[id];
sum[rson]=(r-mid)*lazy[id];
lazy[lson]=lazy[rson]=lazy[id];
lazy[id]=-1;
}
void add(int id,int L,int R,int l,int r,int v)
{
//cout<<L<<" "<<R<<" "<<l<<" "<<r<<endl;
if(L>r||R<l) return ;
if(L>=l&&R<=r)
{
lazy[id]=v;
sum[id]=(R-L+1)*v;
return ;
}
int mid=(L+R)>>1;
pd(id,L,R,mid);
add(lson,L,mid,l,r,v);
add(rson,mid+1,R,l,r,v);
sum[id]=sum[lson]+sum[rson];
}
int getans(int id,int L,int R,int l,int r)
{
if(L>r||R<l) return 0;
if(L>=l&&R<=r) return sum[id];
int mid=(L+R)>>1;
pd(id,L,R,mid);
int ret=getans(lson,L,mid,l,r)+getans(rson,mid+1,R,l,r);
return ret;
}
int tim[N*75],val[N*75],tot,ls[N*75],rs[N*75];
int rt[N];
void down(int id)
{
if(tim[id]==-1) return;
++tot;tim[tot]=tim[id];ls[tot]=ls[ls[id]];rs[tot]=rs[ls[id]];ls[id]=tot;val[tot]=val[id];
++tot;tim[tot]=tim[id];ls[tot]=ls[rs[id]];rs[tot]=rs[rs[id]];rs[id]=tot;val[tot]=val[id];
tim[id]=-1;
}
void build(int pre,int &now,int L,int R,int l,int r,int t,int v)
{
now=++tot;
if(L>=l&&R<=r)
{
tim[now]=t;
val[now]=v;
return ;
} //cout<<L<<" "<<R<<" "<<l<<" "<<r<<endl;
if(pre) down(pre);
ls[now]=ls[pre],rs[now]=rs[pre];
int mid=(L+R)>>1;
if(mid>=l) build(ls[pre],ls[now],L,mid,l,r,t,v);
if(mid+1<=r) build(rs[pre],rs[now],mid+1,R,l,r,t,v);
}
int get(int id,int l,int r,int pos)
{
if(!id||tim[id]!=-1) return id;
int mid=(l+r)>>1;
if(pos<=mid) return get(ls[id],l,mid,pos);
return get(rs[id],mid+1,r,pos);
}
void del(int x,int y)
{
int id=get(rt[y-1],1,n,x);
if(!id)
{
rt[y]=rt[y-1];
return ;
}
// if(tim[id]==0) while(1);
id=get(rt[tim[id]-1],1,n,x);
build(rt[y-1],rt[y],1,n,x,x,tim[id],val[id]);
add(1,1,n,x,x,val[id]);
}
void change(int l,int r,int v,int i)
{
build(rt[i-1],rt[i],1,n,l,r,i,v);
add(1,1,n,l,r,v);
}
int ty;
int ans;
int main()
{
scanf("%d%d%d",&n,&m,&ty);
memset(lazy,-1,sizeof(lazy));
memset(tim,-1,sizeof(tim));
for(int i=1,aa,bb,cc,dd;i<=m;i++)
{
scanf("%d",&aa);
if(aa==1)
{
scanf("%d%d",&bb,&cc);
bb=(bb+ans*ty)%n+1;
cc=(cc+ans*ty)%n+1;
if(bb>cc) swap(bb,cc);
ans=getans(1,1,n,bb,cc);
printf("%d\n",ans);
rt[i]=rt[i-1];
}
else if(aa==2)
{
scanf("%d",&bb);
bb=(bb+ans*ty)%n+1;
del(bb,i);
}
else if(aa==3)
{
scanf("%d%d%d",&bb,&cc,&dd);
bb=(bb+ans*ty)%n+1;
cc=(cc+ans*ty)%n+1;
if(bb>cc) swap(bb,cc);
change(bb,cc,dd,i);
}
}
}