Traveling Merchant
https://ac.nowcoder.com/acm/contest/13168/L
用14棵或7棵线段树来维护每种情况,维护max,min,最大差值还有最小差值,复杂度O(n)*14/O(n)*7
然后查询,复杂度O(logn)
难点在于找树
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long ull;
typedef long double lld;
#define lson p<<1
#define rson p<<1|1
const int N = 1e5+5;
const int seed = 26;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double esp = 1e-7;
int n,m,s,t;
struct node{
int l;
int r;
int maxx;
int minn;
int mx;
int mn;
}tree[14][N<<2];
int v[N],d[N],a[N];
node pushup(node a,node b){
node res;
res.l=a.l;
res.r=b.r;
res.maxx=max(a.maxx,b.maxx);
res.minn=min(a.minn,b.minn);
res.mx=max(max(a.mx,b.mx),b.maxx-a.minn);
res.mn=min(min(a.mn,b.mn),b.minn-a.maxx);
return res;
}
void build(int l,int r,int p,int num){
tree[num][p].l=l,tree[num][p].r=r;
if(l==r){
tree[num][p].maxx=a[l];
tree[num][p].minn=a[l];
tree[num][p].mn=INF;
tree[num][p].mx=-INF;
return;
}
int mid=(l+r)>>1;
build(l,mid,lson,num);
build(mid+1,r,rson,num);
tree[num][p]=pushup(tree[num][lson],tree[num][rson]);
}
node query(int l,int r,int p,int num){
if(tree[num][p].l>=l&&tree[num][p].r<=r)
return tree[num][p];
int mid=(tree[num][p].l+tree[num][p].r)>>1;
if(mid>=r) return query(l,r,lson,num);
if(l>mid) return query(l,r,rson,num);
node L = query(l,r,lson,num);
node R = query(l,r,rson,num);
return pushup(L,R);
}
ll qpow(ll a,ll b){
ll ans=1,base=a;
while(b){
if(b&1) ans=ans*base;
base=base*base;
b>>=1;
}
return ans;
}
int find(int l,int r){
if(l<=r)
return (8-l%7)%7;
else{
l%=7;
if(l==0) l=7;
return 6+l;
}
}
void solve(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %d",&v[i],&d[i]);
}
for(int j=0;j<7;j++){
for(int i=1;i<=n;i++){
int day=(i+j)%7;
if(day==0||day==1) a[i]=v[i];
else if(day==2||day==6) a[i]=v[i]+d[i];
else if(day==3||day==5) a[i]=v[i]+2*d[i];
else a[i]=v[i]+3*d[i];
}
build(1,n,1,j);
}
for(int j=7;j<14;j++){
int cnt=j%7+1;
int day;
for(int i=1;i<=n;i++){
day=cnt;
if(day==1||day==7) a[i]=v[i];
else if(day==2||day==6) a[i]=v[i]+d[i];
else if(day==3||day==5) a[i]=v[i]+2*d[i];
else a[i]=v[i]+3*d[i];
cnt--;
if(cnt==0) cnt=7;
}
//for(int i=1;i<=n;i++) cout<<a[i]<<" ";
//cout<<endl;
build(1,n,1,j);
}
scanf("%d",&m);
while(m--){
scanf("%d %d",&s,&t);
int tt=find(s,t);
//cout<<tt<<endl;
node res=query(min(s,t),max(s,t),1,tt);
printf("%d\n",s<=t?max(0,res.mx):max(0,-res.mn));
}
}
int main(){
int Case=1;
//init();
//scanf("%d",&Case);
//getchar();
while(Case--){
solve();
}
return 0;
}
/*
1 0
2 6
3 5
4 4
5 3
6 2
7 1
*/