洛谷 P4145 上帝造題的七分鐘2 / 花神遊歷各國

題目連接

題目描述

 

題目分析

 這道題其實是一道動態RSQ(區間求和問題),很容易想到使用線段樹來解決。但咱們發現,和的開方並不等於開方的和,也就是說咱們不可以經過直接對某一段區間的和進行開方來改變某一個區間的喜歡度——咱們只能對區間裏的每個值分別進行更改再求和。ide

但這樣的區間修改的時間複雜度難以承受。因而咱們要尋求優化的方法。咱們注意到,sqrt(1)=1,也就是說對於1開方的過程是能夠省略的。因爲數列中的數均爲正整數,若是區間的和等於區間的長度,就說明區間裏全部數均爲1,那麼咱們就能夠不用修改這個區間從而剪枝。優化

代碼

 1 #include<algorithm>
 2 #include<cmath>
 3 #include<cstdio>
 4 using namespace std;
 5 long long n,m,x,order,t1,t2,sumof[400001];
 6 void fastinput(long long &temp)
 7 {
 8     temp=0;
 9     char now=getchar();
10     while(now<'0'||now>'9')
11         now=getchar();
12     while(now>='0'&&now<='9')
13     {
14         temp=temp*10+now-'0';
15         now=getchar();
16     }
17     return;
18 }
19 void fastoutput(long long temp)
20 {
21     if(temp>9)
22         fastoutput(temp/10);
23     putchar(temp%10+'0');
24     return;
25 }
26 void fastoutputln(long long temp)
27 {
28     fastoutput(temp);
29     putchar('\n');
30     return;
31 }
32 void add(long long no,long long l,long long r,long long place,long long value)
33 {
34     if(place>r||place<l)
35         return; 
36     if(l==r&&l==place)
37     {
38         sumof[no]+=value;
39         return;
40     }
41     long long mid=l+r>>1;
42     add(no<<1,l,mid,place,value);
43     add(no<<1|1,mid+1,r,place,value);
44     sumof[no]=sumof[no<<1]+sumof[no<<1|1];
45     return;
46 }
47 void change(long long no,long long l,long long r,long long x,long long y)
48 {
49     if(sumof[no]<=r-l+1)
50         return;
51     if(x>r||y<l)
52         return; 
53     if(l==r&&x<=l&&r<=y)
54     {
55         sumof[no]=(long long)sqrt(sumof[no]);
56         return;
57     }
58     long long mid=l+r>>1;
59     change(no<<1,l,mid,x,y);
60     change(no<<1|1,mid+1,r,x,y);
61     sumof[no]=sumof[no<<1]+sumof[no<<1|1];
62     return;
63 }
64 long long query(long long no,long long l,long long r,long long x,long long y)
65 {
66     if(x<=l&&r<=y)
67         return sumof[no];
68     long long mid=l+r>>1,result=0LL;
69     if(x<=mid)
70         result+=query(no<<1,l,mid,x,y);
71     if(mid<y)
72         result+=query(no<<1|1,mid+1,r,x,y);
73     return result;
74 }
75 int main()
76 {
77     fastinput(n);
78     for(long long i=1;i<=n;++i)
79     {
80         fastinput(x);
81         add(1,1,n,i,x);
82     }
83     fastinput(m);
84     for(long long i=1;i<=m;++i)
85     {
86         fastinput(order);
87         fastinput(t1);
88         fastinput(t2);
89         if(t1>t2)
90             swap(t1,t2);
91         if(order==1)
92             fastoutputln(query(1,1,n,t1,t2));
93         else
94             change(1,1,n,t1,t2);
95     }
96     return 0;
97 }
上帝造題的七分鐘2 / 花神遊歷各國
相關文章
相關標籤/搜索