Doom HDU - 5239 (找规律+线段树)

 题目链接:

 题目大意:首先是T组测试样例,然后n个数,m次询问,然后每一次询问给你一个区间,问你这个这段区间的加上上一次的和是多少,查询完之后,这段区间里面的每个数变为原来的平方。

具体思路:这个模数,和正常的模数不一样。

然后通过打表能发现,每个数不断自身平方对p取模后经过有限次 就不会变化了,

测试少于30次

所以也就是说每个节点至多会被更新30次。

注意会爆long long ,需要用unsigned long long .

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define inf 0x3f3f3f3f
 4 # define ull unsigned long long
 5 # define lson l,mid,rt<<1
 6 # define rson mid+1,r,rt<<1|1
 7 const int maxn = 4e5+100;
 8 const ull mod = 9223372034707292160;
 9 struct node
10 {
11     ull sum;
12     int flag;
13 } tree[maxn];
14 ull qsmu(ull t1,ull t2)
15 {
16     ull ans=0ll;
17     while(t2)
18     {
19         if(t2&1)
20             ans=(ans+t1)%mod;
21         t2>>=1;
22         t1=(t1+t1)%mod;
23     }
24     return ans;
25 }
26 ull tot;
27 void up(int rt)
28 {
29     tree[rt].sum=(tree[rt<<1].sum+tree[rt<<1|1].sum)%mod;
30     tree[rt].flag=(tree[rt<<1].flag&tree[rt<<1|1].flag);
31 }
32 void build(int l,int r,int rt)
33 {
34     tree[rt].flag=0;
35     tree[rt].sum=0;
36     if(l==r)
37     {
38         scanf("%lld",&tree[rt].sum);
39         return ;
40     }
41     int mid=l+r>>1;
42     build(lson);
43     build(rson);
44     up(rt);
45 }
46 void update(int l,int r,int rt,int L,int R)
47 {
48     if(R<l||r<L||tree[rt].flag)
49         return ;
50     if(l==r)
51     {
52         ull tmp=tree[rt].sum;
53         tree[rt].sum=qsmu(tree[rt].sum,tree[rt].sum);
54         if(tmp==tree[rt].sum)
55             tree[rt].flag=1;
56         return ;
57     }
58     int mid=(l+r)>>1;
59     update(lson,L,R);update(rson,L,R);
60     up(rt);
61 }
62 void ask(int l,int r,int rt,int L,int R)
63 {
64     if(R<l||r<L)
65         return ;
66     if(L<=l&&R>=r)
67     {
68         tot=(tot+tree[rt].sum)%mod;
69         return ;
70     }
71     int mid=(l+r)>>1;
72     ask(lson,L,R);ask(rson,L,R);
73     up(rt);
74 }
75 int main()
76 {
77     int T;
78     int Case=0;
79     scanf("%d",&T);
80     while(T--)
81     {
82         tot=0;
83         int m,n;
84         scanf("%d %d",&n,&m);
85         build(1,n,1);
86         printf("Case #%d:\n",++Case);
87         while(m--)
88         {
89             int l,r;
90             scanf("%d %d",&l,&r);
91             ask(1,n,1,l,r);
92             printf("%lld\n",tot);
93             update(1,n,1,l,r);
94         }
95     }
96     return 0;
97 }

 

posted @ 2019-04-29 16:52  Let_Life_Stop  阅读(226)  评论(0编辑  收藏  举报