首页 > 其他 > 详细

HDU5239

时间:2015-09-06 21:25:25      阅读:295      评论:0      收藏:0      [点我收藏+]

http://acm.hdu.edu.cn/showproblem.php?pid=5239

Doom

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 722    Accepted Submission(s): 181


Problem Description
THE END IS COMINGGGGGG!

Mike has got stuck on a mystery machine. If he cannot solve this problem, he will go to his doom.

This machine is consist of n cells, and a screen. The i-th cell contains a number ai(1in). The screen also contains a number s, which is initially 0.

There is a button on each cell. When the i-th is pushed, Mike observes that, the number on the screen will be changed to s+ai, where s is the original number. and the number on the i-th cell will be changed to a2i.

Mike observes that the number is stored in radix p, where p=9223372034707292160. In other words  , the operation is under modulo p

And now, Mike has got a list of operations. One operation is to push buttons between from l-th to r-th (both included), and record the number on the screen. He is tired of this stupid work, so he asks for your help. Can you tell him, what are the numbers recorded.

 

 

Input
The first line contains an integer T(T5), denoting the number of test cases.

For each test case, the first line contains two integers n,m(1n,m105).

The next line contains n integers ai(0ai<p), which means the initial values of the n cells.

The next m lines describe operations. In each line, there are two integers l,r(1lrn), representing the operation.

 

 

Output
For each test case, output ‘‘Case #t:‘‘, to represent this is the t-th case. And then output the answer for each query operation, one answer in a line.

For more details you can take a look at the example.
 
Sample Input
2
4 4
2 3 4 5
1 2
2 3
3 4
1 4
1 3
2
1 1
1 1
1 1
 
Sample Output
Case #1:
5
18
39
405
Case #2:
2
6
22
 

 

Source
 
题目大意:(典型的线段树模型。。。。)给你n个数,有m次询问,每次询问要求输出区间[l,r]中,从l到r所有数字的和加到答案中并对p=9223372034707292160取模,之后还要对从l到r的每个数更新,即对期间的每个数平方。并且对于p这个数,任何一个数平方对p这个数取模最多29次,之后就会是不变的数,所以更新时判断更新次数是否等于30,如果是则不用向下更新,否则继续向下更新。
需要注意的是,当(p-1)*(p-1)时,直接相乘会溢出,所以此处要用到快速加法(也是看了题解才想到)。
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #define mod 9223372034707292160
  7 #define ll unsigned __int64
  8 using namespace std;
  9 ll n, m, a[1000006], sum;
 10 struct node{
 11     ll l, r, sum, lazy;
 12 }t[1001000*2];
 13 void pushup(ll i){
 14     t[i].sum = (t[i*2].sum + t[i*2+1].sum)%mod;
 15     t[i].lazy = min(t[i*2].lazy,t[i*2+1].lazy);
 16 }
 17 void build(ll i, ll l, ll r){
 18     t[i].l = l;
 19     t[i].r = r;
 20     if(l == r){
 21         t[i].sum = a[l];
 22         t[i].lazy = 0;
 23         return ;
 24     }
 25     ll mid = (l+r)/2;
 26     build(i*2, l, mid);
 27     build(i*2+1, mid+1, r);
 28     pushup(i);
 29 }
 30 ll fun(ll a, ll b){//快速加法防止a*b溢出
 31     ll sum = 0;
 32     while(b){
 33         if(b & 1){
 34             sum = (sum + a) % mod;
 35             printf(" %I64d\n",sum);
 36         }
 37         b /= 2;
 38         a = (a*2) % mod;
 39         //printf("  %I64d\n",a);
 40     }
 41     return sum;
 42 }
 43 
 44 void update(ll i, ll x, ll y){
 45     if(t[i].lazy == 30)
 46         return ;
 47     ll l = t[i].l;
 48     ll r = t[i].r;
 49     if(l == x && y == r && x == y){
 50         t[i].sum = fun(t[i].sum,t[i].sum);//快速加法防止a*b溢出
 51         t[i].lazy++;
 52         //printf(" %I64d\n",t[i].sum);
 53         return ;
 54     }
 55     ll mid = (l+r)/2;
 56     if(x > mid)
 57         update(i*2+1, x, y);
 58     else if(y <= mid)
 59         update(i*2, x, y);
 60     else{
 61         update(i*2+1, mid+1, y);
 62         update(i*2, x, mid);
 63     }
 64     pushup(i);
 65 }
 66 
 67 ll query(ll i, ll x, ll y){
 68     ll l = t[i].l;
 69     ll r = t[i].r;
 70     if(l == x && r == y)
 71         return t[i].sum;
 72     ll mid = (l+r)/2;
 73     if(y <= mid)
 74         return (query(i*2, x, y))%mod;
 75     else if(x > mid)
 76         return (query(i*2+1, x, y))%mod;
 77     else
 78         return (query(i*2, x, mid)+query(i*2+1, mid+1, y))%mod;
 79 }
 80 
 81 int main()
 82 {
 83     int i, j, T, x, y;
 84     int cas = 1;
 85     scanf("%d",&T);
 86     while(T--){
 87         scanf("%I64d%I64d",&n,&m);
 88         for(i = 1; i <= n; i++)
 89             scanf("%I64d",&a[i]);
 90         build(1, 1, n);
 91         printf("Case #%d:\n",cas++);
 92         sum = 0;
 93         while(m--){
 94             scanf("%d%d",&x,&y);
 95             sum = (sum + query(1, x, y))%mod;
 96             printf("%I64d\n",sum);
 97             update(1, x, y);
 98         }
 99     }
100     return 0;
101 }

 


HDU5239

原文:http://www.cnblogs.com/acm31415/p/4787115.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!