zoukankan      html  css  js  c++  java
  • 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) ight))完成. 而对于每次修改(a[i])的值, 也可以在(O left(sqrt(n) * log(n) ight))的时间复杂度内完成维护.

    #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('
    ');
    }
    
    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));
    	}
    }
    
  • 相关阅读:
    工单系统的设计与实现(4)
    java_tcp_简单示例
    java_udp编程
    mysql 锁问题 (相同索引键值或同一行或间隙锁的冲突)
    行锁与表锁详解
    BTree和B+Tree详解
    深入浅出java常量池
    MySQL三大范式和反范式
    java多线程 栅栏CyclicBarrier
    SpringBoot初始教程之Servlet、Filter、Listener配置
  • 原文地址:https://www.cnblogs.com/ZeonfaiHo/p/6436745.html
Copyright © 2011-2022 走看看