HDU-4627(セグメントツリー)
3585 ワード
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 50110;
int MIN[11][maxn<<2];
int col[11][maxn<<2];
int id[11][maxn],vis[11][maxn];
void build(int l,int r,int rt){
for(int i=1;i<=10;i++) MIN[i][rt]=0;
for(int i=1;i<=10;i++) col[i][rt]=0;
if(l==r) return ;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void pushup(int l,int r,int rt,int i){
MIN[i][rt]=min(MIN[i][rt<<1],MIN[i][rt<<1|1]);
}
void pushdown(int l,int r,int rt,int i){
if(l==r){
col[i][rt]=0;
return ;
}
if(col[i][rt]){
col[i][rt<<1]+=col[i][rt];
MIN[i][rt<<1]+=col[i][rt];
col[i][rt<<1|1]+=col[i][rt];
MIN[i][rt<<1|1]+=col[i][rt];
col[i][rt]=0;
}
}
int ql,qr,addv;
void update(int l,int r,int rt,int i){
if(ql<=l&&r<=qr){
col[i][rt]+=addv;
MIN[i][rt]+=addv;
// cout<<l<<"-->"<<r<<" "<<(r-l+1)*addv<<endl;
return ;
}
pushdown(l,r,rt,i);
int m=(l+r)>>1;
if(ql<=m) update(lson,i);
if(qr> m) update(rson,i);
pushup(l,r,rt,i);
}
int res;
int posi;
void query(int l,int r,int rt,int i){
if(l==r){
res+=MIN[i][rt];
// cout<<l<<"-->"<<r<<" "<<sum[i][rt]<<endl;
return ;
}
pushdown(l,r,rt,i);
int m=(l+r)>>1;
if(posi<=m) query(lson,i);
else if(posi> m) query(rson,i);
}
int lim = 50010;
int find(int yu,int wei,int i){
int x=0,y=lim;
while(x<y){
int m = x + (y - x)/2;
if(id[i][m]%i>yu) y=m;
else if(id[i][m]%i<yu) x=m+1;
else {
if(id[i][m]/i==wei) return m;
if(id[i][m]/i >wei) y=m;
else x = m+1;
}
// cout<<m<<" "<<id[i][m]<<" "<<id[i][m]%i<<endl;
}
}
int query_id(int st,int ed,int k,int i){
int x = st % k;
int l = 0,r=lim;
while(l<r){ //
int m = l + ( r- l)/2;
if(x + m*k>=st) r=m;
else l=m+1;
}
int si = l; // cout<<"start-->"<<si<<endl;
l = 0,r=lim;
while(l<r){ //
int m = l + ( r- l)/2;
if(x + m*k<=ed) l=m+1;
else r=m;
}
int ei = l-1; // cout<<"end-->"<<ei<<endl;
ql = find(x,si,i);
qr = find(x,ei,i);
}
int main()
{
for(int i=1;i<=10;i++){
int te=0;
for(int j=0;j<i;j++){
for(int k=j;k<lim;k+=i){
id[i][te++]=k;
}
}
int n;
while(scanf("%d",&n)==1){
for(int i=0;i<n;i++){
scanf("%d",&id[0][i]);
}
build(0,lim,1);
int Q;
scanf("%d",&Q);
while(Q--){
int cmd;
scanf("%d",&cmd);
if(cmd==1){
int a,b,k;
scanf("%d %d %d %d",&a,&b,&k,&addv);
query_id(a,b,k,k);
update(0,lim,1,k);
}
else {
int pos;
scanf("%d",&pos);
res=0;
res+=id[0][pos-1];
for(int i=1;i<=10;i++){
int yu= pos%i,wei=pos/i;
posi=find(yu,wei,i);
query(0,lim,1,i);
}
printf("%d
",res);
}
}
}
return 0;
}