关于昨晚Div4.F的线段树的问题
  • 板块学术版
  • 楼主Chancylaser
  • 当前回复13
  • 已保存回复13
  • 发布时间2023/2/4 12:28
  • 上次更新2023/10/24 01:45:33
查看原帖
关于昨晚Div4.F的线段树的问题
241817
Chancylaser楼主2023/2/4 12:28

RT。

这份代码的 pushup函数被我打的分界线分成了两块,这两块按理说写哪一块的正确性都能保证,但是写第一块能AC,但是第二块会Wa on 2。

求解/kel。

#include <bits/stdc++.h>
#define ll long long
using namespace std;

typedef long long LL;
inline int read(){
	int s=0,k=1;
	char c=getchar();
	while(c>'9'||c<'0'){
		if(c=='-')k=-k;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		s=(s<<3)+(s<<1)+(c^48);
		c=getchar();
	}
	return s*k;
} 

const int N=3e5+10; 
int n,m,op,x,y,tt;
ll a[N];
struct node{
	int l,r;
	int v,add;
	Tree(){
		l=r=0;
		v=add=0ll;
	}
	void Change(int k){
		int len=r-l+1;
		v+=1ll*k*len;
		add+=k;
		return;
	}
}t[N<<2];
node c;
node operator+(const node &a,const node &b){
	c.l=a.l, c.r=b.r;
	c.v=a.v+b.v;
	return c;
}	

void pushup(int s){
//----------------------------------------------
	t[s]=t[s<<1]+t[s<<1|1]; 
//----------------------------------------------
	t[s].l=t[s<<1].l, t[s].r=t[s<<1|1].r;
	t[s].v=t[s<<1].v+t[s<<1|1].v;
//----------------------------------------------
}

void pushdown(int p){
	if(t[p].add){
		t[p<<1].Change(t[p].add);
		t[p<<1|1].Change(t[p].add);
		t[p].add=0ll;
	}
	return;
}

void build(int s,int l,int r){
    t[s].l=l;t[s].r=r;
    if(l==r){
    	t[s].v=0;
    	t[s].add=0;
    	return;
	}
	int mid=(l+r)>>1;
	build(s<<1,l,mid);
	build(s<<1|1,mid+1,r);
	pushup(s);
	//t[s]=t[s<<1]+t[s<<1|1];
}

void Addsum(int p,int l,int r,int v){
	if(t[p].r<l||t[p].l>r) return;
	if(t[p].l>=l&&t[p].r<=r){
		t[p].Change(v);
		return;
	}
	pushdown(p);
	
	Addsum(p<<1,l,r,v);
	Addsum(p<<1|1,l,r,v);
	t[p]=t[p<<1]+t[p<<1|1];
	return;
}

LL Getsum(int p,int l,int r){
	if(t[p].r<l||t[p].l>r) return 0ll;
	if(t[p].l>=l&&t[p].r<=r) return t[p].v;
	pushdown(p);
	
	return Getsum(p<<1,l,r)+Getsum(p<<1|1,l,r);
}

int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
		build(1,1,n);
		
		for(int kk=1;kk<=m;kk++){
			scanf("%d",&op);
			if(op==1){
				scanf("%d%d",&x,&y);
				Addsum(1,x,y,1);
			}
			else{
				scanf("%d",&x);
				int t=Getsum(1,x,x);
				if(a[x]<=9){
					printf("%lld\n",a[x]);
					continue;
				}
				int sum,mm;
				for(int j=1;j<=t;j++){
					sum=0;
					if(a[x]==1e9) a[x]=1;
					else{
						for(mm=10;mm<=1e9;mm*=10)
							sum+=a[x]%mm/(mm/10);
						a[x]=sum;							
					}
					if(a[x]<=9) break;	
				}
				if(a[x]>=10) Addsum(1,x,x,-t);
				printf("%lld\n",a[x]);
			}
		}		
	}
	return 0;
}
2023/2/4 12:28
加载中...