cf765F.Souvenirs

比赛的时候看错了C题于是不会做了……来搞F,听说有人莫队水过去了,于是也写了个莫队,TLE7……惨掉rating

editorial看得很烦躁啊……又回想起了被英语阅读支配的恐惧

离线,移动右端点,考虑维护左端点处的答案.设当前右端点移动到了i,数列为a[],则答案的更新一定是由a[i]与某些a[j](j<i)的差的绝对值引起的,下面只考虑a[j]≥a[i]的情况,a[j]≤a[i]同理(当然如果有a[j]=a[i]会被用来更新2次但是肯定不会影响答案正确性)

首先我们找出最大的一个j满足j<i,a[j]≥a[i],用它更新[1,j]的答案。设a[j]=y,那么在[1,j-1]中如果有a的值大于y,肯定不会对答案构成影响(因为它与a[i]的差大于a[j]-a[i]),实际上,我们发现对于a数列中任何一个位于[1,j-1]的数,当且仅当它处于[a[i],(a[i]+a[j])/2]时,才可能与a[i]成对,对前面的答案造成影响,如果一个元素的值位于((a[i]+a[j])/2,a[j]],那么它肯定会与a[j]成对。这样一来,我们就把需要考虑的值域从[a[i],1e9]缩短到了[a[i],(a[i]+a[j])/2],重复这个过程,每次都至少会把这个区间折半,于是更新答案的次数是O(log(1e9))的,更新答案的过程用一个区间取min的线段树维护,寻找某一值域中最右元素可用一个动态开点的权值线段树维护,于是总时间复杂度为O(nlog2MaxV+mlogn),如果把a[]离散化之后开权值线段树可以做到O(nlognlogMaxV+mlogn),其中MaxV=1e9.

  1 program cf765F;
  2 uses math;
  3 const maxn=100000+10;
  4       maxm=300000+10;
  5       maxv=1000000000;
  6 type query=record next,l,r:longint;end;
  7 var a,last:array[0..maxn] of longint;
  8     ques:array[0..maxm] of query;
  9     ans:array[0..maxm] of longint;
 10     mark:array[0..maxn*4] of longint;
 11     segv:array[0..maxn*40] of record l,r,right:longint;end;
 12     n,m,root,tot,i,j,l,r,id:longint;
 13 procedure build(x,l,r:longint);
 14 var mid:longint;
 15 begin
 16   mark[x]:=maxv+1;
 17   if l<r then
 18   begin
 19     mid:=(l+r)shr 1;
 20     build(x+x,l,mid);
 21     build(x+x+1,mid+1,r);
 22   end;
 23 end;
 24 procedure update(x,l,r,nowl,nowr,v:longint);
 25 var mid:longint;
 26 begin
 27   if(nowl<=l)and(r<=nowr) then
 28   begin
 29     mark[x]:=min(mark[x],v);
 30     exit;
 31   end;
 32   mid:=(l+r)shr 1;
 33   if nowl<=mid then update(x+x,l,mid,nowl,nowr,v);
 34   if nowr>mid then update(x+x+1,mid+1,r,nowl,nowr,v);
 35 end;
 36 function ask(x,l,r,p:longint):longint;
 37 var mid:longint;
 38 begin
 39   if l=r then exit(mark[x]);
 40   mid:=(l+r)shr 1;
 41   if p<=mid then exit(min(mark[x],ask(x+x,l,mid,p)))
 42     else exit(min(mark[x],ask(x+x+1,mid+1,r,p)));
 43 end;
 44 function findright(x,l,r,nowl,nowr:longint):longint;
 45 var mid:longint;
 46 begin
 47   if((nowl<=l)and(r<=nowr))or(x=0) then exit(segv[x].right);
 48   mid:=(l+r)shr 1;
 49   if nowr<=mid then exit(findright(segv[x].l,l,mid,nowl,nowr));
 50   if nowl>mid then exit(findright(segv[x].r,mid+1,r,nowl,nowr));
 51   exit(max(findright(segv[x].l,l,mid,nowl,nowr),findright(segv[x].r,mid+1,r,nowl,nowr)));
 52 end;
 53 procedure modify(var x:longint;l,r,p,v:longint);
 54 var mid:longint;
 55 begin
 56   if x=0 then
 57   begin
 58     inc(tot);
 59     x:=tot;
 60   end;
 61   segv[x].right:=max(segv[x].right,v);
 62   if l<r then
 63   begin
 64     mid:=(l+r)shr 1;
 65     if p<=mid then modify(segv[x].l,l,mid,p,v)
 66       else modify(segv[x].r,mid+1,r,p,v);
 67   end;
 68 end;
 69 begin
 70   readln(n);
 71   for i:=1 to n do read(a[i]);
 72   readln(m);
 73   for i:=1 to m do readln(ques[i].l,ques[i].r);
 74   fillchar(last,sizeof(last),0);
 75   for i:=1 to m do
 76   begin
 77     ques[i].next:=last[ques[i].r];
 78     last[ques[i].r]:=i;
 79   end;
 80   build(1,1,n);
 81   root:=0;
 82   tot:=0;
 83   segv[0].right:=0;
 84   for i:=1 to n do
 85   begin
 86     if i>1 then
 87     begin
 88       l:=a[i];
 89       r:=maxv;
 90       while true do
 91       begin
 92         id:=findright(root,0,maxv,l,r);
 93         if id=0 then break;
 94         update(1,1,n,1,id,a[id]-a[i]);
 95         if a[i]=a[id] then break;
 96         r:=(a[i]+a[id])shr 1;
 97       end;
 98       l:=0;
 99       r:=a[i];
100       while true do
101       begin
102         id:=findright(root,0,maxv,l,r);
103         if id=0 then break;
104         update(1,1,n,1,id,a[i]-a[id]);
105         if a[i]=a[id] then break;
106         l:=(a[i]+a[id])shr 1+1;
107       end;
108     end;
109     j:=last[i];
110     while j>0 do
111     begin
112       ans[j]:=ask(1,1,n,ques[j].l);
113       j:=ques[j].next;
114     end;
115     modify(root,0,maxv,a[i],i);
116   end;
117   for i:=1 to m do writeln(ans[i]);
118 end.

时间: 2024-10-23 17:23:18

cf765F.Souvenirs的相关文章

【CF765F】Souvenirs 主席树

[CF765F]Souvenirs 题意:给你一个长度为n的序列{ai},有m个询问,每次询问给出l,r,问在所有$l\le x < y\le r$中,$|a_x-a_y|$的最小值是多少. $n\le 10^5,m\le 3\times 10^5,a_i\le 10^9$ 题解:网上的标程都是在线段树上搞一搞就完事了,但是我怎么看都觉得是$O(n\log^3n)$的.看官方题解,里面也没写具体做法.于是我一脸懵逼的情况下用了主席树来维护,起码保证了$O(n\log^2n)$的复杂度.(应该是做

hdoj 2126 Buy the souvenirs 【另类01背包】

题意:求最多购买的件数以及有几种方法. 一看到这题就想到了背包,因为求得是种类数,所以我们可以将件数看做价值,将价格看做重量,这就变成01背包了(dp),但是还要求有几种购买方案,那么再来一个背包(kind). 分析:有三种情况: 1>dp[j] < dp[j-s[i]]+1 那么对于这一种情况  方案背包的状态转移方程是kind[j] = kind[j-s[i]]?kind[j-s[i]]:1;(考虑到kind[j-s[i]] ==0的时候,这时候kind[j] = 1): 证明:为什么是k

Buy the souvenirs (01背包,动归)

When the winter holiday comes, a lot of people will have a trip. Generally, there are a lot of souvenirs to sell, and sometimes the travelers will buy some ones with pleasure. Not only can they give the souvenirs to their friends and families as gift

hdu2126---Buy the souvenirs(01背包方案数)

Problem Description When the winter holiday comes, a lot of people will have a trip. Generally, there are a lot of souvenirs to sell, and sometimes the travelers will buy some ones with pleasure. Not only can they give the souvenirs to their friends

(01背包)HDU - 2126 Buy the souvenirs

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给n个物品,和m块钱,输出最多物品个数和其方案数. 委屈:求出最多物品个数就是一个裸的01背包,但是同时求出方案数,难住了我. 想了半天,感觉可以一波dp求出来,但是又想不明白状态是怎么表示和转移的. 无奈就先写个dfs提交试一发,果断超时了. 最后无奈看了题解,只能说,01背包还是不会. 其实与其说01背包不会不如说动态规划不会,感觉好难. 感觉自己好lowbee啊.. 感觉碰到dp就

[HDU 2126] Buy the souvenirs (动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给你n个物品,m元钱,问你最多能买个多少物品,并且有多少种解决方案. 一开始想到的是,先解决给m元钱因为我花的钱少就一定能购买够多的物品,因此是个贪心算法. 记买最多的物品数为c. 然后就是设计状态dp[i][j]代表我从前i个物品里花了j元钱,买c个物品有多少种方案. 后来发现状态维数不够,得重新想想. 于是就想到: 设计状态dp[i][j][k]代表我从前i个物品里买了j个,花的钱不

hdu 2126 Buy the souvenirs(记录总方案数的01背包)

Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1662    Accepted Submission(s): 611 Problem Description When the winter holiday comes, a lot of people will have a trip. Genera

hdu2126 Buy the souvenirs

Problem Description When the winter holiday comes, a lot of people will have a trip. Generally, there are a lot of souvenirs to sell, and sometimes the travelers will buy some ones with pleasure. Not only can they give the souvenirs to their friends

HDU 2126 Buy the souvenirs

Buy the souvenirs Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 212664-bit integer IO format: %I64d      Java class name: Main When the winter holiday comes, a lot of people will have a trip. Generally, the