codechef Chef and Churu

Approach: Consider dividing the function into blocks (1-root number n, root number n+1-root number 2*n, functions like this)

We can preprocess the sum of several a[i] corresponding to the functions in each block by differential preprocessing

That is, the coefficient k[i] in sigma(a[i]*k[i]), and then preprocess the sum of each block and record it as sum[i]

Considering the modification operation, it is obviously very simple. We can directly change the sum value of each block

Then consider the query operation, and do the whole block casually, but the scattered ones are troublesome.

So use a tree array to record the prefix and sum of a.

The only pit: long long seems to be not enough, you need to open unsigned long long

Code:

#include<bits/stdc++.h>
#define N 500005
#define lll unsigned long long
using namespace std;
lll ll[N],rr[N],a[N],c[N],l[N],r[N],cnt[405][N/5+5],sum[405];
lll n,Q,opt,x,y,block,num;
inline lll gt(lll x){return (x-1)/block+1;}
inline lll lowbit(lll x){return x&-x;}
inline void add(lll x,lll y){for(lll i=x;i<=n;i+=lowbit(i))c[i]+=y;}
inline lll gtsum(lll x){lll ans=0;for(lll i=x;i;i-=lowbit(i))ans+=c[i];return ans;}
inline void change(lll x,lll y){
	add(x,y-a[x]);
	for (lll i=1;i<=num;i++)
		sum[i]+=cnt[i][x]*(y-a[x]);
	a[x]=y;
}
inline lll query(lll x,lll y){
	lll years=0;
	if (gt(x)==gt(y)||gt(x)+1==gt(y))
		for (lll i=x;i<=y&&i<=n;i++) ans+=gtsum(r[i])-gtsum(l[i]);
	else {
		for (lll i=gt(x)+1;i<gt(y);i++) ans+=sum[i];
		for (lll i=x;i<=rr[gt(x)]&&i<=n;i++) ans+=gtsum(r[i])-gtsum(l[i]);
		for (lll i=ll[gt(y)];i<=y&&i<=n;i++) ans+=gtsum(r[i])-gtsum(l[i]);
	}
	return ans;
}
int main(){
	scanf("%llu",&n);block=(lll)sqrt(n);
	for (lll i=1;i<=n;i++) scanf("%llu",&a[i]),add(i,a[i]);
	num=n/block;if (n%block) num++;
	for (lll i=1;i<=num;i++) ll[i]=(i-1)*block+1,rr[i]=i*block;rr[num]=n;
	for (lll i=1;i<=n;i++) scanf("%llu%llu",&l[i],&r[i]),l[i]--;
	for (lll i=1;i<=num;i++){
		for (lll j=ll[i];j<=rr[i];j++){
			cnt[i][l[j]+1]++;
			cnt[i][r[j]+1]--;
		}
	}
	for (lll i=1;i<=num;i++){
		for (lll j=1;j<=n;j++){
			cnt[i][j]+=cnt[i][j-1];
			sum[i]=sum[i]+cnt[i][j]*a[j];
		}
	}
	//printf("%d\n",cnt[2][4]);
	scanf("%llu",&Q);
	while (Q--){
		scanf("%llu%llu%llu",&opt,&x,&y);
		if (opt==1) change(x,y);
		else printf("%llu\n",query(x,y));
	}
	return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325860970&siteId=291194637