BZOJ 3211 花神游历各国 线段树平方开根
题目链接:
https://www.lydsy.com/JudgeOnline/problem.php?id=3211
题目大意:
思路:
由于数据范围只有1e9,一个数字x开根号次数超过logx之后均为1,所以可以暴力开根号,但是需要剪枝优化,如果子树的max小于等于1,那么直接跳过即可。否则递归到叶子节点暴力开根号。
1 #include<bits/stdc++.h> 2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf 3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时 4 #define Min(a, b) ((a) < (b) ? (a) : (b)) 5 #define Mem(a) memset(a, 0, sizeof(a)) 6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1)) 7 #define MID(l, r) ((l) + ((r) - (l)) / 2) 8 #define lson ((o)<<1) 9 #define rson ((o)<<1|1) 10 #define Accepted 0 11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 17 while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 21 typedef long long ll; 22 const int maxn = 100000 + 10; 23 const int MOD = 1000000007;//const引用更快,宏定义也更快 24 const int INF = 1e9 + 7; 25 const double eps = 1e-6; 26 27 ll a[maxn]; 28 struct node 29 { 30 int l, r; 31 ll mmax, sum; 32 }tree[maxn<<2]; 33 void build(int o, int l, int r) 34 { 35 tree[o].l = l, tree[o].r = r; 36 if(l == r) 37 { 38 tree[o].mmax = tree[o].sum = a[l]; 39 return; 40 } 41 int m = MID(l, r); 42 build(lson, l, m); 43 build(rson, m + 1, r); 44 tree[o].mmax = Max(tree[lson].mmax, tree[rson].mmax); 45 tree[o].sum = tree[lson].sum + tree[rson].sum; 46 } 47 int ql, qr; 48 ll sum; 49 void query(int o) 50 { 51 if(ql <= tree[o].l && qr >= tree[o].r) 52 { 53 sum += tree[o].sum; 54 return; 55 } 56 if(ql <= tree[lson].r)query(lson); 57 if(qr >= tree[rson].l)query(rson); 58 } 59 void update(int o) 60 { 61 if(tree[o].mmax <= 1)return; 62 if(tree[o].l == tree[o].r) 63 { 64 tree[o].mmax = tree[o].sum = sqrt(1.0 * tree[o].mmax); 65 return ; 66 } 67 if(ql <= tree[lson].r)update(lson); 68 if(qr >= tree[rson].l)update(rson); 69 tree[o].mmax = Max(tree[lson].mmax, tree[rson].mmax); 70 tree[o].sum = tree[lson].sum + tree[rson].sum; 71 } 72 int main() 73 { 74 int n, m; 75 scanf("%d", &n); 76 for(int i = 1; i <= n; i++)scanf("%d", &a[i]); 77 build(1, 1, n); 78 scanf("%d", &m); 79 while(m--) 80 { 81 int op; 82 scanf("%d%d%d", &op, &ql, &qr); 83 if(op == 1) 84 { 85 sum = 0; 86 query(1); 87 printf("%lld\n", sum); 88 } 89 else 90 { 91 update(1); 92 } 93 } 94 return Accepted; 95 }
越努力,越幸运