您的位置:首页 > 其它

CodeForces 52C Circular RMQ (线段树)

2015-09-05 19:55 363 查看
线段树区间更新维护最小值。。。记得下放标记。。。

如果线段树上的一个完整区间被修改,那么最小值和最大值增加相应的值后不变,

会改变是因为一部分改变而另外一部分没有改变所以维护一下就好。

询问的时候也要记得下放标记。。。

数据结构快忘了,贴个板。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+1;

struct Seg
{
ll lazy;
ll Min;
}tr[maxn<<2];

int a[maxn];
int n;

#define lid (id<<1)
#define rid (id<<1|1)

void build(int l = 0,int r = n-1,int id = 1)
{
if(l == r) { tr[id].Min = a[l]; return; }//tr[rt].lazy }
int mid = (l+r)>>1, lc = lid, rc = rid;
build(l,mid,lc);
build(mid+1,r,rc);
tr[id].Min = min(tr[lc].Min,tr[rc].Min);
}

int ql,qr;
ll val;

#define Modify(id,v) tr[id].lazy += v; tr[id].Min += v;
void updata(int l = 0,int r = n-1,int id = 1)
{
if(ql<=l&&r<=qr) { Modify(id,val)  return; }
int mid = (l+r)>>1, lc = lid, rc = rid;
if(tr[id].lazy){
ll &t = tr[id].lazy;
Modify(lc,t)
Modify(rc,t)
t = 0;
}
if(ql<=mid){
updata(l,mid,lc);
}
if(qr>mid) {
updata(mid+1,r,rc);
}
tr[id].Min = min(tr[lc].Min,tr[rc].Min);
}

const ll INF = 0x3f3f3f3f3f3f3f3f;

ll query(int l = 0,int r = n-1,int id = 1)
{
if(ql<=l&&r<=qr){
return tr[id].Min;
}
int mid = (l+r)>>1,lc = lid, rc = rid;
if(tr[id].lazy){
ll &t = tr[id].lazy;
Modify(lc,t);
Modify(rc,t);
t = 0;
}
ll ret = INF;
if(ql<=mid){
ret = min(ret,query(l,mid,lc));
}
if(qr>mid){
ret = min(ret,query(mid+1,r,rc));
}
return ret;
}

bool sscan_l(int &x,char *&s)
{
while(!isdigit(*s) && *s != '-'){
if(!*s) return false;
s++;
}
bool fg;
if(*s == '-') fg = true,x = 0;
else x = *s-'0',fg = false;

while(s++,isdigit(*s)) x = x*10+*s-'0';
if(fg) x = -x;
return true;
}

char Line[666];
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i = 0; i < n; i++) scanf("%d",a+i);
build();
int m; scanf("%d\n",&m);
while(m--){
gets(Line);
char *p = Line;
int num[3], i;
for(i = 0; i < 3; i++ ){
if(!sscan_l(num[i],p)) break;
}
if(i == 2){
int l = num[0],r = num[1];
if(l<=r) {
ql = l; qr = r;
printf("%I64d\n",query());
}else {
ql = 0; qr = r;
ll ans = query();
ql = l; qr = n-1;
ans = min(ans,query());
printf("%I64d\n",ans);
}
}else {
int l = num[0], r = num[1]; val = num[2];
if(l<=r){
ql = l; qr = r;
updata();
}else {
ql = 0; qr = r;
updata();
ql = l; qr = n-1;
updata();
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: