码迷,mamicode.com
首页 > 其他好文 > 详细

线段树

时间:2019-04-15 20:20:27      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:acm   oid   c++   col   push   build   ace   mat   amp   

题目:hdu 5239

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

这是一个典型的线段树模板,里面的取模很强,mod=9223372034707292160. 这个膜是2的64次方减掉2的32次方的值,某一个数连续平方取模若干以后值不变,这个题就是用这个膜的性质去解决这个问题的,如果不这样操作的话会T的,大概进行29次的平方以后不会变了,使用用一个数组标记该节点,如果该节点被标记了,在更新的时候,就不需要向下更新了,节省非常多的时间了。

技术图片
 1 #include<bits/stdc++.h>
 2 typedef unsigned long long ll;
 3 using namespace std;
 4 ll s[100503<<2];
 5 ll sum[100503<<2];
 6 int b[100503<<2];
 7 void pushup(int p)
 8 {
 9     sum[p]=(sum[p<<1]+sum[p<<1|1])%mod;
10     b[p]=b[p<<1]&b[p<<1|1];
11 }
12 void build(int p,int l,int r)
13 {
14     if(l==r)
15     {
16         sum[p]=s[l];
17         return ;
18     }
19     int mid=(l+r)>>1;
20     build(p<<1,l,mid);
21     build(p<<1|1,mid+1,r);
22     pushup(p);
23 }
24 ll look(int x,int y,int p,int l,int r)
25 { ll ss=0;
26     if(x<=l&&r<=y)
27     {
28         return sum[p];
29     }
30     int mid=(l+r)>>1;
31     if(x<=mid)ss=(ss+look(x,y,p<<1,l,mid))%mod;
32     if(y>mid) ss=(ss+look(x,y,p<<1|1,mid+1,r))%mod;
33     return ss;
34 }
35 ll kc(ll a,ll b)
36 {
37     ll c=0;
38     while(b)
39     {
40         if(b&1)c=(a+c)%mod;
41         a=(a+a)%mod;
42         b>>=1;
43     }return c;
44 }
45 void add(int x,int y,int p,int l,int r)
46 {   if(b[p]&&x<=l&&r<=y)
47        return ;
48     if(l==r)
49     {
50         ll team=kc(sum[p],sum[p]);
51         if(team==sum[p])b[p]=1;
52         sum[p]=team;
53         return ;
54     }
55     int mid=(l+r)>>1;
56    if(x<=mid) add(x,y,p<<1,l,mid);
57     if(y>mid)add(x,y,p<<1|1,mid+1,r);
58     pushup(p);
59 }
60 ll S;
61 int main()
62 {
63  int t;
64   cin>>t;
65  for(int i=1;i<=t;i++)
66  {S=0;mem(b);mem(s);mem(sum);
67     printf("Case #%d:\n",i);
68      ll n,m;
69      sll(n,m);
70      for(int j=1;j<=n;j++)
71         sl(s[j]);
72      build(1,1,n);
73      while(m--)
74      {
75          int x,y;
76          sii(x,y);
77          S=(S+look(x,y,1,1,n))%mod;
78          printf("%lld\n",S);
79          add(x,y,1,1,n);
80      }
81  }
82 }
View Code

 

线段树

标签:acm   oid   c++   col   push   build   ace   mat   amp   

原文地址:https://www.cnblogs.com/zxz666/p/10712494.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!