正题
题目大意
若干个区间操作l,rl,rl,r
让答案增加(l+r)∗max{ai}(i∈[l..r])(l+r)*max\{a_i\}(i\in[l..r])(l+r)∗max{ai}(i∈[l..r])
并把最大的数变为0
解题思路
线段树,上传最大值时多上传一个位置,然后单点修改。
codecodecode
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=200100,XJQ=2011;
struct treenode{int num,val,l,r;
}t[N*4];
int n,m,ans,sum,num;
void Merge(int k)
{if(t[k*2].val>t[k*2+1].val)t[k].val=t[k*2].val,t[k].num=t[k*2].num;else t[k].val=t[k*2+1].val,t[k].num=t[k*2+1].num;
}
void build(int k,int l,int r)
{t[k].l=l;t[k].r=r;if(l==r){scanf("%d",&t[k].val);t[k].num=t[k].l;return;}int mid=(l+r)/2;build(k*2,l,mid);build(k*2+1,mid+1,r);Merge(k);
}
void ask(int k,int l,int r)
{if(t[k].l==l&&t[k].r==r){if(t[k].val<=ans) return;ans=t[k].val;num=t[k].num;return;}int mid=(t[k].l+t[k].r)/2;if(r<=mid) ask(k*2,l,r);else if(l>mid) ask(k*2+1,l,r);else ask(k*2,l,mid),ask(k*2+1,mid+1,r);
}
void change(int k,int x)
{if(t[k].l==t[k].r){t[k].val=0;return;}int mid=(t[k].l+t[k].r)/2;if(x<=mid) change(k*2,x);else change(k*2+1,x);Merge(k);
}
int main()
{//freopen("data.in","r",stdin);scanf("%d%d",&n,&m);build(1,1,n);for(int i=1;i<=m;i++){int l,r;scanf("%d%d",&l,&r);ans=0;ask(1,l,r);(sum+=ans*((l+r)%XJQ)%XJQ)%=XJQ;change(1,num);}printf("%d",sum);
}