上帝造题的七分钟2/花神游历各国

题目传送门

考虑用线段树进行区间求和,暴力修改。

我们发现开根号操作并不能直接像加减一样直接修改,但是他有一个非常良好的性质,对于一个小于等于1e12的数,其进行下取整开根操作至多不超过6次就可以到1,对于1,我们显然不需要进行任何操作,因此修改的复杂度是O(nlogn),数据只有1e5,因此不用在意常数。而线段树直接区间求和的复杂度也是O(nlogn),所以总时间复杂度为O(小常数*nlogn)

 1 #pragma GCC optimize(3,"Ofast","inline")
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 #define N 100005
 8 #define int long long 
 9 using namespace std;
10 int read()
11 {
12     int x=0,f=1;char ch=getchar();
13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
15     return x*f;
16 }
17 int n,m,a[N];
18 struct node
19 {
20     int l,r,sum,maxn;
21 }tree[N*4];
22 void pushup(int k)
23 {
24     tree[k].maxn=max(tree[k*2].maxn,tree[k*2+1].maxn);
25     tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
26 }
27 void build(int l,int r,int k)
28 {
29     tree[k].l=l;tree[k].r=r;
30     if(l==r)
31     {
32         tree[k].sum=tree[k].maxn=a[l];
33         return;
34     }
35     int mid=l+r>>1;
36     build(l,mid,k*2);
37     build(mid+1,r,k*2+1);
38     pushup(k);
39 }
40 void modify(int x,int y,int k)
41 {
42     int l=tree[k].l,r=tree[k].r;
43     if(l==r)
44     {
45         tree[k].sum=sqrt(tree[k].sum);
46         tree[k].maxn=sqrt(tree[k].maxn);
47         return;
48     }
49     int mid=l+r>>1;
50     if(x<=mid&&tree[k*2].maxn>1)modify(x,y,k*2);
51     if(y>mid&&tree[k*2+1].maxn>1)modify(x,y,k*2+1);
52     pushup(k);
53 }
54 int query(int x,int y,int k)
55 {
56     int l=tree[k].l,r=tree[k].r;
57     if(l>=x&&r<=y)return tree[k].sum;
58     int mid=l+r>>1,res=0;
59     if(x<=mid)res+=query(x,y,k*2);
60     if(y>mid)res+=query(x,y,k*2+1);
61     return res;
62 }
63 signed main()
64 {
65     freopen("god.in","r",stdin);
66     freopen("god.out","w",stdout);
67     n=read();
68     for(int i=1;i<=n;i++)a[i]=read();
69     build(1,n,1);
70     m=read();
71     int opt,x,y;
72     while(m--)
73     {
74         opt=read();x=read();y=read();
75         if(x>y)swap(x,y);
76         if(opt==2)modify(x,y,1);
77         else printf("%lld\n",query(x,y,1));
78     }
79     return 0;
80 }
View Code

 

posted @ 2019-10-24 08:09  shao0320  阅读(193)  评论(0编辑  收藏  举报
****************************************** 页脚Html代码 ******************************************