CODECHEF Nov. Challenge 2014 Chef & Churu

@(XSY)[分塊]
Hint: 題目原文是英文的, 寫得很難看, 因此翻譯為中文.
Description

Input Format

First Line is the size of the array i.e. \(N\)
Next Line contains N space separated numbers \(A_i\) denoting the array
Next N line follows denoting \(Li\) and \(Ri\) for each functions.
Next Line contains an integer \(Q\) , number of queries to follow.
Next \(Q\) line follows , each line containing a query of Type 1 or Type 2.
1 x y : denotes a type 1 query,where x and y are integers
2 m n : denotes a type 2 query where m and n are integers

Output Format

For each query of type 2 , output as asked above.

Constraints

\(1 ≤ N ≤ 10^5\)
\(1 ≤ A i ≤ 10^9\)
\(1 ≤ L i ≤ N\)
$L i ≤ R i ≤ N $
\(1 ≤ Q ≤ 10^5\)
$1 ≤ x ≤ N $
\(1 ≤ y ≤ 10^9\)
$1 ≤ m ≤ N \( \)m ≤ n ≤ N$

Subtask

Subtask \(1\): \(N ≤ 1000 , Q ≤ 1000\) , \(10\) points
Subtask \(2\): \(R-L ≤ 10\) , all x will be distinct ,\(10\) points
Subtask \(3\): Refer to constraints above , \(80\) points

Sample Input

5 
1 2 3 4 5 
1 3 
2 5 
4 5 
3 5 
1 2 
4 
2 1 4 
1 3 7 
2 1 4 
2 3 5 

Sample Output

41 
53 
28 

Explanation

Functions values initially :
$F[1] = 1+ 2 + 3 = 6 \( \)F[2] = 2 + 3 + 4 + 5 = 14 \( \)F[3] = 4+5 = 9 \( \)F[4] = 3+4+5 = 12 \( \)F[5] = 1+2 = 3 $
Query \(1\): $F[1] + F[2] + F[3] + F[4] = 41 \( After Update , the Functions are : \)F[1] = 10 , F[2] = 18 , F[3] = 9 , F[4] = 16 , F[5] = 3 $
Query \(3\): $F[1] + F[2] + F[3] + F[4] = 53 $
Query \(4\): \(F[3]+F[4]+F[5] = 28\)

Solution

\(a\)数组建立树状数组维护前缀和;
对函数进行分块处理. 维护两个数组, 其中\(sum[i]\)表示第\(i\)个块中的函数值的总和; \(cnt[i][j]\)表示第\(i\)个块中\(a[j]\)被累加的次数. \(cnt\)数组在预处理时可以通过累加前缀和的方法, \(O \left( n * sqrt(n) \right)\)完成. 而对于每次修改\(a[i]\)的值, 也可以在\(O \left(sqrt(n) * log(n) \right)\)的时间复杂度内完成维护.

#include<cstdio>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;

inline long long read()
{
	long long x = 0, flag = 1;
	char c;
	while(! isdigit(c = getchar()))
		if(c == '-')
			flag *= - 1;
	while(isdigit(c))
		x = x * 10 + c - '0', c = getchar();
	return x * flag;
}

void println(long long x)
{
	if(x < 0)
		putchar('-'), x *= - 1;
	if(x == 0)
		putchar('0');
	long long ans[1 << 5], top = 0;
	while(x)
		ans[top ++] = x % 10, x /= 10;
	for(; top; top --)
		putchar(ans[top - 1] + '0');
	putchar('\n');
}

const long long N = 1 << 17;

long long n;

long long a[N];
long long L[N], R[N];
long long T[N];

inline void modify(long long u, long long x)
{
	for(; u <= n; u += u & - u)
		T[u] += (long long)x;
}

long long unit, num;

long long cnt[1 << 9][N];
long long sum[1 << 9];

void update(long long x, long long y)
{
	for(long long i = 0; i < num; i ++)
		sum[i] += (long long)cnt[i][x] * (y - a[x]);
		
	modify(x, y - a[x]);
	a[x] = y;
}

inline long long query(long long u)
{
	long long ret = 0;
	
	for(; u; u -= u & - u)
		ret += T[u];
		
	return ret;
}

long long ask(long long _L, long long _R)
{
	long long lBlock = _L / unit, rBlock = _R / unit;
	long long ret = 0;
	
	if(lBlock == rBlock)
		for(long long i = _L; i <= _R; i ++)
			ret += query(R[i]) - query(L[i] - 1);
	else
	{
		for(long long i = lBlock + 1; i < rBlock; i ++)
			ret += sum[i];
		
		for(long long i = _L; i < (lBlock + 1) * unit; i ++)
			ret += query(R[i]) - query(L[i] - 1);
			
		for(long long i = unit * rBlock; i <= _R; i ++)
			ret += query(R[i]) - query(L[i] - 1);
	}
	
	return ret;
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("chefAndChurus.in", "r", stdin);
	freopen("chefAndChurus.out", "w", stdout);
	#endif
	
	n = read();
	memset(T, 0, sizeof(T));
	
	for(long long i = 1; i <= n; i ++)
		modify(i, a[i] = read());
	
	for(long long i = 0; i < n; i ++)
		L[i] = read(), R[i] = read();
		
	unit = (long long)sqrt(n);
	long long cur = - 1;
	
	memset(cnt, 0, sizeof(cnt));
	
	for(long long i = 0; i < n; i ++)
	{
		if(i % unit == 0)
			cur ++;
		
		cnt[cur][L[i]] ++, cnt[cur][R[i] + 1] --;
	}
	
	num = cur + 1;
	
	memset(sum, 0, sizeof(sum));
	
	for(long long i = 0; i < num; i ++)
		for(long long j = 1; j <= n; j ++)
		{
			cnt[i][j] += cnt[i][j - 1];
			sum[i] += (long long)cnt[i][j] * a[j];
		}
		
	long long m = read();
	
	for(long long i = 0; i < m; i ++)
	{
		 long long opt = read(), x = read(), y = read();
		 
		 if(opt == 1)
		 	update(x, y);
		else
			println(ask(x - 1, y - 1));
	}
}
posted @ 2017-02-24 08:05  Zeonfai  阅读(297)  评论(0编辑  收藏  举报