博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeForces 1058 F Putting Boxes Together 树状数组,带权中位数
阅读量:7085 次
发布时间:2019-06-28

本文共 2940 字,大约阅读时间需要 9 分钟。

题意:

现在有n个物品,第i个物品他的位置在a[i],他的重量为w[i]。每一个物品移动一步的代价为他的w[i]。目前有2种操作:

1. x y 将第x的物品的重量改为y

2.l r 将编号在 [ l, r ]之间的所有物品移动到一起,求最小的花费是多少。

 

如果移动一个物品移动一步的代价是1的话,对于[1,n]来说,那么中间位置就是 a[(1+n)/2]. 也就是最中间的那个物品的位置。

现在移动一步他的代价是w[i],那么中间位置就是 sum(1,k) >= sum(k+1,n) 在满足前面的条件下,k最小。

我们可以用2分跑出最小的k,这样我们就确定了位置。

接来下我们的问题就是如何移动物品了。

我们可以把所有的物品移动到区间[1,n]上,记录下花费。

然后在把这一整段的物品整体移动到对应区间就好了。

注意的就是对于中间点来说,整体区间移动的正负是不一样的。

代码:

1 #include
2 using namespace std; 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 4 #define LL long long 5 #define ULL unsigned LL 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define lson l,m,rt<<110 #define rson m+1,r,rt<<1|111 #define lch(x) tr[x].son[0]12 #define rch(x) tr[x].son[1]13 #define max3(a,b,c) max(a,max(b,c))14 #define min3(a,b,c) min(a,min(b,c))15 typedef pair
pll;16 const int inf = 0x3f3f3f3f;17 const LL INF = 0x3f3f3f3f3f3f3f3f;18 const LL mod = (int)1e9+7;19 const int N = 2e5 + 100;20 LL tree1[N], tree2[N];21 int n, q;22 int a[N], w[N];23 inline int lowbit(int x){24 return x & (-x);25 }26 void add1(int x, LL v){27 for(int i = x; i <= n; i+=lowbit(i))28 tree1[i] += v;29 }30 void add2(int x, LL v){31 for(int i = x; i <= n; i+=lowbit(i))32 tree2[i] += v;33 }34 LL query1(int x){35 LL ret = 0;36 for(int i = x; i; i -= lowbit(i))37 ret += tree1[i];38 return ret;39 }40 LL query2(int x){41 LL ret = 0;42 for(int i = x; i; i -= lowbit(i))43 ret += tree2[i];44 return ret % mod;45 }46 LL sum1(int l, int r){47 if(l > r) return 0;48 return query1(r) - query1(l-1);49 }50 LL sum2(int l, int r){51 if(l > r) return 0;52 return query2(r) - query2(l-1);53 }54 int GG(int l, int r){55 if(l == r) return 0;56 int ll = l, rr = r, mm;57 LL tot = sum1(l, r), t1 , t2;58 while(ll <= rr){59 mm = ll + rr >> 1;60 t1 = sum1(l, mm);61 t2 = tot - t1;62 if(t1 < t2) ll = mm + 1;63 else rr = mm - 1;64 }65 LL ret = 0;66 ret -= sum2(l,ll-1);67 ret += ((sum1(l,ll-1)%mod) * (a[ll]-1-(ll-1)))%mod;68 ret += sum2(ll+1,r);69 ret -= ((sum1(ll+1,r)%mod) * (a[ll]+1 -(ll+1)))%mod;70 return (ret%mod + mod) % mod;71 }72 int main(){73 scanf("%d%d", &n, &q);74 for(int i = 1; i <= n; i++) scanf("%d", &a[i]);75 for(int i = 1; i <= n; i++){76 scanf("%d", &w[i]);77 add1(i, w[i]);78 LL v = ((1ll*a[i]-i)*w[i])%mod;79 add2(i, v);80 }81 int l, r;82 for(int i = 1; i <= q; i++){83 scanf("%d%d", &l, &r);84 if(l < 0){85 l = -l;86 add1(l, r-w[l]);87 LL v = (((1ll*a[l]-l)*r)%mod)-((1ll*a[l]-l)*w[l])%mod;88 add2(l, v);89 w[l] = r;90 }91 else printf("%d\n", GG(l,r));92 }93 return 0;94 }
View Code

 

转载于:https://www.cnblogs.com/MingSD/p/9718442.html

你可能感兴趣的文章
install eSyndiCat PHP Directory Software onUbuntu
查看>>
线性表的表示和实现方式之链式表示和实现
查看>>
STP选举过程分析
查看>>
Ajax
查看>>
python多线程、多进程、协程的使用
查看>>
C语言版数据结构及算法_快速排序
查看>>
PDF怎么把两个合并成一个?PDF怎么合并?
查看>>
Java面试高频题精选300道,一份通往阿里的必备指南(pdf文档)
查看>>
SQL 2005通用分页存储过程
查看>>
抗TNF治疗的397例AS患者中,CRP和脊柱外受累对 ASDAS疗效的影响
查看>>
Sublime text3配置xdebug调试记录
查看>>
进程同步概念简介 多线程上篇(四)
查看>>
mysql之自定义函数
查看>>
手工SQL注入常用SQL语句
查看>>
20162321 实验一 Java开发环境的熟悉(Linux + Eclipse)
查看>>
一个inline-block的样式。
查看>>
MVC学习第一章
查看>>
我的友情链接
查看>>
Exchange企业实战技巧(1)验证安装及配置产品密钥
查看>>
解决 Exchange2013提示“出现意外错误,无法处理您的请求”,无法打开OWA和ECP
查看>>