首页 > 其他分享 >[USACO23FEB] Hungry Cow P 题解

[USACO23FEB] Hungry Cow P 题解

时间:2024-10-11 20:32:24浏览次数:8  
标签:ch log Cow mathit 题解 Hungry 答案 ans 区间

T7 [USACO23FEB] Hungry Cow P

这题就比较正常了,蓝紫之间的水平。

我们发现 Bessie 能活 \(10^{14}\) 天(,导致我们不好直接按照值域来维护。发现给某一天送干草,影响到的是后面很多天,这是个区间问题。所以考虑动态开点线段树。线段树的每个节点维护 \(\mathit{ans},\mathit{cnt},\mathit{out}\),分别表示当前区间答案、当前区间有多少天能吃上饭、当前区间有多少溢出。

不好维护的地方在于解决左儿子向右儿子 “溢出” 的问题。设 \(f(l,r,x)\) 表示前面溢出了 \(x\) 份干草给区间 \([l,r]\) 时这个区间有多少天能吃上饭。对于这个函数的求解,分类讨论:

  • \(x=0\),直接返回区间 \([l,r]\) 的 \(\mathit{ans}\);
  • \(l=r\),直接返回 \(l\);
  • \(x-\mathit{cnt}_l\le\mathit{mid}-l+1\),说明 \(x\) 份干草让左区间用完了,递归左区间并加上右区间的答案。注意右区间的答案不是 \(\mathit{ans}_r\),而是 \(\mathit{ans}_p-\mathit{ans}_l\),因为右区间的答案我们暂时没有更新,我们只能用我们已经更新过的当前区间答案和左区间答案相减得到。
  • 否则说明,左区间全都可以吃到干草,等差数列求和统计左区间答案,然后递归计算右区间。

核心部分就讲完了,感觉还是挺技巧的。注意动态开点线段树的空间复杂度是 \(O(n\log n)\) 的。时间复杂度是线段树的 \(n\log n\) 乘上 \(f\) 函数计算的一个 \(\log\),总共 \(O(n\log^2n)\)。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
#define lp st[p].ls
#define rp st[p].rs
#define mid ((s+t)>>1)
using namespace std;

char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
template<typename T=int>
T read(){
	T x=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x;
}
template<typename T>
void write(T x,char sf='\n'){
	if(x<0)putchar('-'),x=~x+1;
	int top=0;
	do str[top++]=x%10,x/=10;while(x);
	while(top)putchar(str[--top]+48);
	putchar(sf);
}
using ll=long long;
constexpr int MAXN=1e5+5;
constexpr ll MOD=1e9+7,inv2=500000004;
int U;
struct SegTree{
	int ls,rs;
	ll ans,cnt,out;
}st[MAXN*47];
int rt=1,tot=1;
ll sum(ll l,ll r){
	return (l+r)%MOD*((r-l+1)%MOD)%MOD*inv2%MOD;
}
ll f(ll s, ll t, ll x, int p){
	if(!x)return st[p].ans;
	if(s==t)return s%MOD;
	if(x+st[lp].cnt<=mid-s+1)return(f(s,mid,x,lp)+st[p].ans-st[lp].ans+MOD)%MOD;
	return(sum(s,mid)+f(mid+1,t,x-(mid-s+1-st[lp].cnt)+st[lp].out,rp))%MOD; 
}
void pushup(ll s,ll t,int p){
	st[p].cnt=st[lp].cnt+min(st[lp].out+st[rp].cnt,t-mid);
	st[p].out=st[rp].out+max(st[lp].out+st[rp].cnt-(t-mid),0ll);
	st[p].ans=(st[lp].ans+f(mid+1,t,st[lp].out,rp))%MOD;
}
void update(ll s,ll t,ll x,ll k,int&p){
	if(!p)p=++tot;
	if(s==t){
		if(!k)st[p].ans=st[p].cnt=st[p].out=0;
		else st[p].cnt=1,st[p].out=k-1,st[p].ans=s%MOD;
		return;
	}
	if(x<=mid)update(s,mid,x,k,lp);
	else update(mid+1,t,x,k,rp);
	pushup(s,t,p);
}

int main(){
	U=read();
	while(U--){
		ll x=read<ll>(),y=read<ll>();
		update(1,2e14,x,y,rt);
		write(st[rt].ans);
	}
	return fw,0;
}

标签:ch,log,Cow,mathit,题解,Hungry,答案,ans,区间
From: https://www.cnblogs.com/laoshan-plus/p/18442118

相关文章

  • csp-s真题题解
    csp题目讲解P8818[CSP-S2022]策略游戏学习笔记感觉非常复杂?对于现在的我还是有深度的,首先第一个大坑就是并不需要真的求出c矩阵,这个题意就是让你在区间中选数,但要求乘积最大,所以要分讨。你假定\(a_i\ge0\),那这时如果\(min(b_i)\ge0\)取\(max(a_i)\),否则取\(min(a_i\ge......
  • P3959 [NOIP2017 提高组] 宝藏 题解
    P3959[NOIP2017提高组]宝藏题解搜索魅力时刻怎么说,四种做法比较??的模拟退火跑得快但是正确性有问题的状压DP跑得慢但是一定正确的状压DP时间复杂度很玄学的DFS+剪枝我就选择了搜索的做法先打个暴搜,70pts点击查看暴搜代码#include<bits/stdc++.h>usingna......
  • 有关 OneDrive 中 Copilot 的常见问题解答
    很多小伙伴已经用上了OneDrive中的Copilot功能:Copilot重磅更新!OneDrive全新功能炸裂一个技巧实现在SharePoint中使用Copilot针对大家提问比较多的问题,在此做一个汇总:1、OneDrive中的Copilot目前在哪里可用?OneDrive中的Copilot目前在 OneDriveWeb上仅适用于商......
  • P5547 [BJ United Round #3] 三色树 题解
    Description请你对满足以下要求的\(n\)个节点的无标号无根树计数:每个节点是三种颜色之一:红,蓝,黄红色节点度数不超过\(4\),蓝色和黄色节点度数均不超过\(3\)黄色节点不能相邻注意无标号无根树的意义是:如果两颗树可以通过重新编号的方法使得对应点颜色相同,对应连边一致......
  • 颠倒原理题解
    颠倒原理/reverse时间限制:1000ms空间限制:512MB题目描述\(GreenDuck\)想学习转置原理,但由于它太难了,因此他转而学习更为简单的和图的染色有密切联系的“颠倒原理”\((reverseprinciple)\)。颠倒原理中有个重要的操作叫做“颠倒操作”。对于一个无向连通图\(G\),其节点要么......
  • 数据结构题解报告
    [GDOI2016]疯狂动物城对于大多树上区间问题往往加个树剖就能变成普通区间问题,只是说复杂度会加个\(log\),出题人这么做的理由可能是想锻炼一下评测姬吧选手的码力吧。而强制在线只需要可持久化数据结构即可。本题同理可视作区间问题用线段树维护,考虑推式子降次以便于维护\(ans......
  • [AGC054D] (ox) 题解
    感觉看到交换就应该要想到逆序对。思路一个前置小知识,我们把一个排列用相邻交换复原的最小次数是逆序对数量。考虑没有ox的情况。我们顺着扫一遍字符串。把左括号正一,右括号看作负一,当前缀和小于零以后,我们把后面最近的左括号提过来,这样可以构造出交换次数最少的合法括号串......
  • 【学校训练记录】十月个人训练赛1题解
    A只需按照题目意思扩展h倍即可,先记录初始字符,打印时扩展为2*h根据题目公式打印`include<bits/stdc++.h>defineintlonglongusingnamespacestd;constintMAXN=100005;intn;inta[MAXN];charmp[105][105];signedmain(){inth,w;cin>>h>>w;for(inti=......
  • CF959F Mahmoud and Ehab and yet another xor task 题解
    题目传送门前置知识线性基解法将操作离线下来,并按\(\{l\}\)升序排序,接着顺序插入线性基并处理询问。对于未成功插入线性基的元素\(k\)一定能被线性基内选出若干元素得到。故在\(x\)能被表出的情况下,设\(1\siml\)中成功插入线性基的元素个数为\(siz\),对于剩下\(......
  • IEEE全球极限编程大赛10.0题目题解:给出数字N,A,B,求出A,B之间与N互质的数的和(数据范围大)
    题目题目来源第10届IEEE极限编程大赛https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/inti-setsInordertomotivatehisPeruvianstudents,ateacherincludeswordsintheQuechualanguageinhismathclass.Today,hedefinedacurious......