• 士兵杀敌(四)(树状数组++思维)


    题目描述:

    南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来帮助小工吧。

    假设起始时所有人的军功都是0.

    输入描述:

    只有一组测试数据。
    每一行是两个整数T和M表示共有T条指令,M个士兵。(1<=T,M<=1000000)
    随后的T行,每行是一个指令。
    指令分为两种:
    一种形如
    ADD 100 500 55 表示,第100个人到第500个人请战,最终每人平均获得了55军功,每次每人获得的军功数不会超过100,不会低于-100。
    第二种形如:
    QUERY 300 表示南将军在询问第300个人的军功是多少。

    输出描述:

    对于每次查询输出此人的军功,每个查询的输出占一行。
    

    样例输入:

    复制
    4 10
    ADD 1 3 10
    QUERY 3
    ADD 2 6 50
    QUERY 3

    样例输出:

    10
    

    60

    AC代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define INF 0x3f3f3f3f
    
    const int maxn = 1e6+5;
    
    int v[maxn];
    int n,m;
    
    void update(int pos,int val)
    {
    	while(pos <= m){
    		v[pos] += val;
    		pos += (pos & (-pos));
    	}
    }
    
    int query(int pos)
    {
    	int rec = 0;
    	while(pos > 0)
    	{
    		rec += v[pos];
    		pos -= (pos & (-pos));
    	}
    	return rec;
    }
    
    int main()
    {
    	scanf("%d %d",&n,&m);
    	memset(v,0,sizeof(v));
    	char a[10];
    	int b,c,d;
    	while( n-- )
    	{
    		scanf("%s",a);
    		if(a[0] == 'A'){
    			scanf("%d %d %d",&b,&c,&d);
    			update(b,d);
    			update(c + 1,-d);
    			for(int i = 0;i<=m;i++){
    				printf("%d ",v[i]);
    			}printf("
    ");
    		} else if (a[0] == 'Q' ) {
    			scanf("%d",&b);
    			printf("%d
    ",query(b));
    		}
    	}
    	
    	return 0;
    }
  • 相关阅读:
    6美元进公园随便挖钻石

    别了,四方
    九种感觉叫爱情,你遭遇过哪一种?(转)
    我提出辞职,老板竟然让我做选择题(转)
    五大绝招让你永远是人才
    人生必读十大启迪(1):生活到底是什么
    创业95%失败不是因项目本身
    穷国和富国差别在哪里
    一个丑女的感情独白
  • 原文地址:https://www.cnblogs.com/Nlifea/p/11746007.html
Copyright © 2020-2023  润新知