[CodeForces 52C]Circular RMQ

题目传送门

评分:省选/NOI-,难度:普及+/提高

这题真的和RMQ没有半点关系,只需要一个裸的线段树,连pushdown都不需要,只需要两种操作:区间修改和区间求最小值,在回溯时加上标记即可,唯一有点思维含量的是对环的处理,如果左端点大于了右端点,就维护(l,n)(1,r),否则正常维护即可,不知道线段树怎么打的可以看我的博客:线段树

下面给出参考代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 struct node
 6 {
 7     long long l,r,w,tag;
 8 }tree[800005];
 9 long long n,m,q,x,y,k,ans;
10 void build(long long l,long long r,long long k)
11 {
12     tree[k].l=l;tree[k].r=r;
13     if(l==r)
14     {
15         scanf("%lld",&tree[k].w);
16         return;
17     }
18     long long mid=(l+r)/2;
19     build(l,mid,k*2);
20     build(mid+1,r,k*2+1);
21     tree[k].w=min(tree[k*2].w,tree[k*2+1].w);
22 }
23 void add(long long k,long long w,long long ll,long long rr)
24 {
25     long long l=tree[k].l,r=tree[k].r;
26     if(l>=ll&&r<=rr)
27     {
28         tree[k].tag+=w;
29         return;
30     }
31     //cout<<k<<" "<<l<<" "<<r<<endl;
32     long long mid=(l+r)/2;
33     //cout<<x<<" "<<y<<endl;
34     if(ll<=mid)add(k*2,w,ll,rr);
35     if(rr>mid)add(k*2+1,w,ll,rr);
36     tree[k].w=min(tree[k*2].w+tree[k*2].tag,tree[k*2+1].w+tree[k*2+1].tag);
37     return;
38 }
39 long long query(long long k,long long ll,long long rr)
40 {
41     if(tree[k].l>=ll&&tree[k].r<=rr)
42     {
43         return tree[k].w+tree[k].tag;
44     }
45     if(tree[k].l>rr||tree[k].r<ll)
46     {
47         return 213704440000;
48     }
49     long long mid=(tree[k].l+tree[k].r)/2,lc,rc;
50     lc=query(k*2,ll,rr);
51     rc=query(k*2+1,ll,rr);
52     return min(lc,rc)+tree[k].tag;
53 }
54 int main()
55 {
56     cin>>n;
57     build(1,n,1);
58     cin>>m;
59     for(long long i=1;i<=m;i++)
60     {
61         cin>>x>>y;
62         x++;y++;
63         char c=getchar();
64         if(c=='
')
65         {
66             //4 1
67             ans=213744040000;
68             if(x>y)cout<<min(query(1,x,n),query(1,1,y));
69             else cout<<query(1,x,y);
70             cout<<endl;
71         }
72         else 
73         {
74             cin>>q;
75             if(x>y)add(1,q,x,n),add(1,q,1,y);
76             else add(1,q,x,y);
77         }
78     }
79     return 0;
80 }
View Code
原文地址:https://www.cnblogs.com/szmssf/p/11068619.html