CodeForces438D The Child and Sequence(线段树取模)

这是一篇关于利用线段树处理序列的数学问题,包括区间求和、取模和修改单个元素操作。文章讨论了在操作过程中如何优化时间复杂度,特别是针对取模操作时,若x大于区间最大值则直接退出,以确保复杂度在O(mlognlogW)内。此外,提到了类似问题如区间开方和分块方法的应用,并列举了相关题目链接供进一步研究。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简化版题意:
给定一个长度为n的非负整数序列a,你需要支持以下操作:
1:给定l,r,输出a[l]+a[l+1]+…+a[r]。
2:给定l,r,x,将a[l],a[l+1],…,a[r]对x取模。
3:给定k,y,将a[k]修改为y。
n,m<=100000,a[i],x,y<=109。

用线段树维护区间最大值以及区间和。
进行取模操作时,如果x>区间最大值那么退出,否则两边都递归下去。
单个数被有效地取模一次只会花费O(logn)的时间,并且数值至少减半,因此每次修改至多使时间复杂度增加O(lognlogW)。
时间复杂度O(mlognlogW)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long 
 using namespace std;
const int MAXN=1000100;
struct JKX{
  int l,r,maxx;
  ll  w;
}t[MAXN*4+100];
int n,T;
void upto(int k)
{
   t[k].w=t[k*2].w+t[k*2+1].w;
   t[k].maxx=max(t[k*2].maxx,t[k*2+1].maxx);
}
void build(int k,int l,int r)
{
	t[k].l=l; t[k].r=r;
	if(l==r) { scanf("%lld",&t[k].w);  t[k].maxx=t[k].w; return;}
	int mid=(l+r)/2; 
	build(k*2,l,mid);
	build(k*2+1,mid+1,r);
    upto(k);
}
void change2(int k,int x,int v)
{
  if(t[k].l==t[k].r) { t[k].w=v; t[k].maxx=v; return;}
  int mid=(t[k].l+t[k].r)/2;
  if(x<=mid) change2(k*2,x,v);
   else change2(k*2+1,x,v);
  upto(k);
}
void change1(int k,int l,int r,int mod)
{
  if(l<=t[k].l && r>=t[k].r && mod>t[k].maxx) return;
  if(t[k].l==t[k].r) {t[k].w%=mod; t[k].maxx=t[k].w; return;}
  int mid=(t[k].l+t[k].r)/2;
  if(l<=mid) change1(k*2,l,r,mod);
   if(r>mid) change1(k*2+1,l,r,mod);
  upto(k);
}
ll get(int k,int l,int r)
{
	if(l<=t[k].l && r>=t[k].r) return (ll)t[k].w;
	int mid=(t[k].l+t[k].r)/2;
	long long J=0;
	if(l<=mid) J+=get(k*2,l,r);
	 if(r>mid) J+=get(k*2+1,l,r);
	return J;
}
int main()
{ 
  scanf("%d%d",&n,&T);
  build(1,1,n);
  int opt,l,r,mod;
  for(int i=1;i<=T;i++)
  { 
    scanf("%d",&opt);
    if(opt==1) { scanf("%d%d",&l,&r); printf("%lld\n",get(1,l,r)); }
    if(opt==2) { scanf("%d%d%d",&l,&r,&mod); change1(1,l,r,mod);}
    if(opt==3) { scanf("%d%d",&l,&r);  change2(1,l,r);}
  }
  return 0;	
} 

类似问题区间开方 在固定次数后区间全变成1 就不用修改了。
题目 hluoj 680
分块版本:

#include<bits/stdc++.h>
 using namespace std;
const int MAXN=50050;
int a[MAXN],f[MAXN],bl[MAXN],sum[MAXN];
int n,blo;
void change(int l,int r)
{   
  if(!f[bl[l]]) 
   {
   	for(int i=l;i<=min(r,bl[l]*blo);i++)  sum[bl[l]]-=(a[i]-sqrt(a[i])),a[i]=sqrt(a[i]);
   }
  if(!f[bl[r]] && bl[r]!=bl[l])
   {
   	for(int i=(bl[r]-1)*blo+1;i<=r;i++) sum[bl[r]]-=(a[i]-sqrt(a[i])),a[i]=sqrt(a[i]);
   }
  for(int i=bl[l]+1;i<=bl[r]-1;i++)
  {
  	if(f[i]) continue;
  	sum[i]=0; f[i]=1;
  	for(int j=(i-1)*blo+1;j<=i*blo;j++) 
  	 {
  	 	a[j]=sqrt(a[j]),sum[i]+=a[j];
  	   	if(a[j]>1) f[i]=0; 
	 }
  }
}
int get(int l,int r)
{
	int J=0;
	for(int i=l;i<=min(r,bl[l]*blo);i++) J+=a[i];
	if(bl[l]!=bl[r])
	 for(int i=(bl[r]-1)*blo+1;i<=r;i++) J+=a[i];
	for(int i=bl[l]+1;i<=bl[r]-1;i++)  J+=sum[i]; 
    return J;
}
int main()
{
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);	
  cin>>n; blo=sqrt(n);
  for(int i=1;i<=n;i++) scanf("%d",&a[i]);
  for(int i=1;i<=n;i++) bl[i]=(i-1)/blo+1,sum[bl[i]]+=a[i];
  int opt,l,r,c;
  for(int i=1;i<=n;i++)
  {
    scanf("%d%d%d%d",&opt,&l,&r,&c);
    if(opt==0) change(l,r);
    if(opt==1) printf("%d\n",get(l,r));
  }
  return 0;
}

线段树版本有一题 BZOJ 3211 花神游历各国 还没写过(哭)
还有区间取对数什么的 , 做到题目再写(开坑)

### Codeforces 1487D Problem Solution The problem described involves determining the maximum amount of a product that can be created from given quantities of ingredients under an idealized production process. For this specific case on Codeforces with problem number 1487D, while direct details about this exact question are not provided here, similar problems often involve resource allocation or limiting reagent type calculations. For instance, when faced with such constraints-based questions where multiple resources contribute to producing one unit of output but at different ratios, finding the bottleneck becomes crucial. In another context related to crafting items using various materials, it was determined that the formula `min(a[0],a[1],a[2]/2,a[3]/7,a[4]/4)` could represent how these limits interact[^1]. However, applying this directly without knowing specifics like what each array element represents in relation to the actual requirements for creating "philosophical stones" as mentioned would require adjustments based upon the precise conditions outlined within 1487D itself. To solve or discuss solutions effectively regarding Codeforces' challenge numbered 1487D: - Carefully read through all aspects presented by the contest organizers. - Identify which ingredient or component acts as the primary constraint towards achieving full capacity utilization. - Implement logic reflecting those relationships accurately; typically involving loops, conditionals, and possibly dynamic programming depending on complexity level required beyond simple minimum value determination across adjusted inputs. ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; vector<long long> a(n); for(int i=0;i<n;++i){ cin>>a[i]; } // Assuming indices correspond appropriately per problem statement's ratio requirement cout << min({a[0], a[1], a[2]/2LL, a[3]/7LL, a[4]/4LL}) << endl; } ``` --related questions-- 1. How does identifying bottlenecks help optimize algorithms solving constrained optimization problems? 2. What strategies should contestants adopt when translating mathematical formulas into code during competitive coding events? 3. Can you explain why understanding input-output relations is critical before implementing any algorithmic approach? 4. In what ways do prefix-suffix-middle frameworks enhance model training efficiency outside of just tokenization improvements? 5. Why might adjusting sample proportions specifically benefit models designed for tasks requiring both strong linguistic comprehension alongside logical reasoning skills?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值