HDU

来源:互联网 发布:计算机组成原理 知乎 编辑:程序博客网 时间:2024/06/11 09:52

Can you answer these queries?

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 18765    Accepted Submission(s): 4425


Problem Description
A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of our secret weapon, it could decrease the endurance of a consecutive part of battleships by make their endurance to the square root of it original value of endurance. During the series of attack of our secret weapon, the commander wants to evaluate the effect of the weapon, so he asks you for help.
You are asked to answer the queries that the sum of the endurance of a consecutive part of the battleship line.

Notice that the square root operation should be rounded down to integer.
 

Input
The input contains several test cases, terminated by EOF.
  For each test case, the first line contains a single integer N, denoting there are N battleships of evil in a line. (1 <= N <= 100000)
  The second line contains N integers Ei, indicating the endurance value of each battleship from the beginning of the line to the end. You can assume that the sum of all endurance value is less than 263.
  The next line contains an integer M, denoting the number of actions and queries. (1 <= M <= 100000)
  For the following M lines, each line contains three integers T, X and Y. The T=0 denoting the action of the secret weapon, which will decrease the endurance value of the battleships between the X-th and Y-th battleship, inclusive. The T=1 denoting the query of the commander which ask for the sum of the endurance value of the battleship between X-th and Y-th, inclusive.
 

Output
For each test case, print the case number at the first line. Then print one line for each query. And remember follow a blank line after each test case.
 

Sample Input
101 2 3 4 5 6 7 8 9 1050 1 101 1 101 1 50 5 81 4 8
 

Sample Output
Case #1:1976
 

Source
The 36th ACM/ICPC Asia Regional Shanghai Site —— Online Contest
 

Recommend
lcy



题意就是有一排战舰,每个战舰都有一个耐久度,每收到一次攻击耐久度都会变为原来的平方根, 0代表输入的区域内收到攻击,1代表查询对应的区域,所以我为啥不说是l,r区域收到攻击呢, 因为这题的坑点就在先输入的不一定是小的它可能攻击3到1区域(也就是1到3区域先输入的是3,我是看讨论区才知道的l可以比r大..。

这个题要注意的就是区间修改的时候,对于已经全部是1的区间就不用修改了,因为1开平方还是1,而且还会超时,我刚开始一直超时,然后我就每次修改的时候看区间内是不是全部是1,对于全部是1的就不用再修改了,然后就ac了...........

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;long long int s[110000<<2];int n;void build(int l, int r, int x){if(l == r){scanf("%lld",&s[x]);return;}int m = (l + r) >> 1;build(l,m,x<<1);build(m+1,r,x<<1|1);s[x] = s[x<<1] + s[x<<1|1];}long long int Query(int i, int j, int l, int r, int x){if(l >= i && r <= j){return s[x];}int m = (l + r) >> 1;long long int ans = 0;if(i <= m)ans += Query(i,j,l,m,x<<1);if(j > m)ans += Query(i,j,m+1,r,x<<1|1);return ans;}void Updata(int i, int j, int l, int r, int x){    if(Query(l,r,1,n,1) <= r - l + 1)///如果所查询的区间和恰好等于区间长度说明区间内全是1,就不用修改了没有这一步会tle        return;if(l == r){s[x] = sqrt(s[x]);return;}int m = (l + r) >> 1;if(i <= m)Updata(i,j,l,m,x<<1);if(j > m)Updata(i,j,m+1,r,x<<1|1);s[x] = s[x<<1] + s[x<<1|1];}int main(){int m, t, i, j, x = 1;while(scanf("%d",&n) != EOF){build(1,n,1);scanf("%d",&m);printf("Case #%d:\n",x++);while(m--){scanf("%d %d %d",&t, &i, &j);if(i > j)///注意i可以比j大,这才是最坑的                swap(i,j);if(t == 0)Updata(i,j,1,n,1);elseprintf("%lld\n",Query(i,j,1,n,1));}printf("\n");}return 0;}


原创粉丝点击