【GDOI2017第三轮模拟day1】影魔(主席树)
来源:互联网 发布:阿里云虚拟主机能装ss 编辑:程序博客网 时间:2024/05/16 18:23
Description
影魔,奈文摩尔,据说有着一个诗人的灵魂。事实上,他吞噬的诗人灵魂早已成千上万。千百年来,他收集了各式各样的灵魂,包括诗人、牧师、帝王、乞丐、奴隶、罪人,当然,还有英雄。
每一个灵魂,都有着自己的战斗力,而影魔,靠这些战斗力提升自己的攻击。
奈文摩尔有n个灵魂,他们在影魔宽广的体内可以排成一排,从左至右标号1到n。第i个灵魂的战斗力为k[i],灵魂们以点对的形式为影魔提供攻击力,对于灵魂对i,j(i
Solution
首先肯定要处理出一个数左边第一个比他大l[i]的和右边第一个比它大的r[i]
那么第一种贡献只有点对(l[i],r[i])才会有贡献
如果询问的区间是[x,y]
那么第一种贡献和sum1=
这种情况是向下折再向上折的情况。
那么我们要怎么求第二种情况呢?
但是我们有两个限制的话会很难做,座椅我们考虑把min给去掉。
那么我们可以发现我们的
那么我们要怎么去求
我们设i这个地方为最大的,只考虑右边
左边同理,那么这个东西在线用主席树做一下就好了。
Code
#include<iostream>#include<stdio.h>#include<algorithm>#include<math.h>#include<string.h>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)using namespace std;typedef long long ll;const int maxn=2e5+7;int i,j,k,n,m,an[maxn];int a[maxn],l[maxn],r[maxn],x,y,q;int root[2][maxn],num,c[maxn];ll yi,er,ans1,ans,p1,p2,sum;struct node{ int l,r; ll sum,size;}t[2][maxn*50];void insert(int y,int &x,int l,int r,int z,int o){ t[o][x=++num]=t[o][y]; t[o][x].sum+=z;t[o][x].size++; if(l==r)return; int mid=(l+r)/2; if(z<=mid)insert(t[o][y].l,t[o][x].l,l,mid,z,o); else insert(t[o][y].r,t[o][x].r,mid+1,r,z,o);}void findl(int y,int x,int l,int r,int z){ if(l==r){er+=t[0][x].size-t[0][y].size;sum+=t[0][x].sum-t[0][y].sum;return;} int mid=(l+r)/2; if(z<=mid){ er+=t[0][t[0][x].r].size-t[0][t[0][y].r].size;sum+=t[0][t[0][x].r].sum-t[0][t[0][y].r].sum; findl(t[0][y].l,t[0][x].l,l,mid,z); } else{yi+=t[0][t[0][x].l].size-t[0][t[0][y].l].size;findl(t[0][y].r,t[0][x].r,mid+1,r,z);}}void findr(int y,int x,int l,int r,int z){ if(l==r){yi+=t[1][x].size-t[1][y].size,sum+=t[1][x].sum-t[1][y].sum;return;} int mid=(l+r)/2; if(z<=mid){er+=t[1][t[1][x].r].size-t[1][t[1][y].r].size;findr(t[1][y].l,t[1][x].l,l,mid,z);} else{ yi+=t[1][t[1][x].l].size-t[1][t[1][y].l].size;sum+=t[1][t[1][x].l].sum-t[1][t[1][y].l].sum; findr(t[1][y].r,t[1][x].r,mid+1,r,z); }}int main(){ freopen("sf.in","r",stdin); freopen("sf.out","w",stdout); scanf("%d%d%d%d",&n,&m,&p1,&p2); fo(i,1,n){ scanf("%d",&a[i]); while(c[0]&&a[c[c[0]]]<=a[i])r[c[c[0]--]]=i; if(c[0])l[i]=c[c[0]]; c[++c[0]]=i; } fo(i,1,n)r[i]=(!r[i])?n+1:r[i]; fo(i,1,n) insert(root[0][i-1],root[0][i],0,n+1,l[i],0),insert(root[1][i-1],root[1][i],0,n+1,r[i],1); fo(i,1,m){ scanf("%d%d",&x,&y);ans=ans1=0; yi=er=sum=0;findl(root[0][x-1],root[0][y],0,n+1,x);ans+=er; yi=er=sum=0;findl(root[0][x-1],root[0][y],0,n+1,x-1);sum+=er;ans1-=sum+yi*x; yi=er=sum=0;findr(root[1][x-1],root[1][y],0,n+1,y);ans+=yi; yi=er=sum=0;findr(root[1][x-1],root[1][y],0,n+1,y+1);sum-=yi;ans1+=sum+er*y; ans=(ans1-ans)*p2+ans*p1; printf("%lld\n",ans); }}
1 0
- 【GDOI2017第三轮模拟day1】影魔(主席树)
- [JZOJ5073]【GDOI2017第三轮模拟day1】影魔
- 【JZOJ5073】【GDOI2017第三轮模拟day1】影魔
- 【jzoj5073】【GDOI2017第三轮模拟day1】【影魔】【数据结构】
- JZOJ 【GDOI2017第三轮模拟day1】单旋
- 【jzoj5072】【GDOI2017第三轮模拟day1】【单旋】【数据结构】
- [JZOJ5072]【GDOI2017第三轮模拟day1】单旋
- GDOI2017第三轮模拟总结
- GDOI2017第三轮模拟总结
- GDOI2017模拟第三轮总结
- 【JZOJ5077】【GDOI2017第三轮模拟day2】树的难题
- 【GDOI2017第二轮模拟day1】最长路径
- 【GDOI2017第二轮模拟day1】公路建设
- 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设
- 【GDOI2017第三轮模拟day2】树的难题(点剖,树状数组)
- 【JZOJ5078】【GDOI2017第三轮模拟day2】魔法咒语
- jzoj 5060. 【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树
- 【GDOI2017第二轮模拟day1】公路建设(克鲁斯卡尔最小生成树+线段树+归并)
- 阿里云ubuntu 14安装mysql
- HashMap HashTable ConCurrentHashMap
- Fiddler对手机或模拟器的网络请求抓包
- RTX:RTX系统调用函数分类、声明、功能及注意事项
- swift 判断/比较两张图片是否相同
- 【GDOI2017第三轮模拟day1】影魔(主席树)
- Swift3.0学习之GCD
- NC portal通过表头主键查询子表vo数据集合
- Maven依赖治理的规则
- 用递归的方法实现输出一个十进制数的每一位
- RTX:多个任务实例、外部引用、信箱使用
- 上传图片
- 手把手教你深度定制tiny4412安卓5.0系统(一)---开发板如何预置文件到android系统
- 树状数组