首页 > 其他分享 >hdu4027(线段树区间操作)

hdu4027(线段树区间操作)

时间:2024-05-20 21:41:03浏览次数:22  
标签:ll int 线段 战列舰 hdu4027 区间 include sum define

Problem - 4027 (hdu.edu.cn)
许多邪恶的战舰在战斗前排成一排。我们的指挥官决定使用我们的秘密武器来消灭战列舰。每艘战列舰都可以标记为耐力值。对于我们秘密武器的每一次攻击,它都可能降低连续部分战列舰的续航能力,使它们的续航力达到其原始续航力值的平方根。在我们的秘密武器的一系列攻击中,指挥官想要评估武器的效果,所以他向你寻求帮助。
您被要求回答以下问题:战列舰线连续部分的耐力之和。

请注意,平方根运算应向下舍入为整数。

输入

输入包含多个测试用例,由 EOF 终止。
对于每个测试用例,第一行包含一个整数 N,表示一行中有 N 艘邪恶的战舰。(1 <= N <= 100000)
第二行包含N个整数Ei,表示每艘战列舰从该行开始到结束的续航值。您可以假设所有耐力值的总和小于 263
下一行包含一个整数 M,表示操作和查询的数量。(1 <= M <= 100000)
对于以下 M 行,每行包含三个整数 T、X 和 Y。T=0表示秘密武器的动作,这将降低第X号和第Y号战列舰之间的战列舰的续航值。T=1 表示指挥官的查询,要求战列舰在 X 号和 Y 号之间的耐力值之和,包括在内。

输出

对于每个测试用例,请在第一行打印案例编号。然后为每个查询打印一行。请记住,在每个测试用例之后都要跟一个空行。


思路

使用线段树。因为一个数x连续开方最终到1只需要很少的次数,所以我们当更新区间的时候直接暴力更新,而且一旦发现区间和小于等于区间长度代表不需要更新了。其余操作均为线段树处理区间的通用操作,贴出代码:

 1 #define IO std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
 2 #define bug(x) cout<<#x<<" is "<<x<<endl
 3 #include <iostream>
 4 #include <list>
 5 #include <unordered_map>
 6 #include <map>
 7 #include <vector>
 8 #include <sstream>
 9 #include <cmath>
10 #include <algorithm>
11 #define iter ::iterator
12 using namespace  std;
13 typedef long long ll;
14 typedef pair<int,int>P;
15 #define pb push_back
16 #define mk make_pair
17 #define se second
18 #define fi first
19 #define rs o*2+1
20 #define ls o*2
21 const ll mod=1e9+7;
22 const int N=1e5+5;
23 
24 
25 int n;
26 
27 ll a[N],sum[N*4];
28 
29 
30 void build(int o,int l,int r){
31     if(l==r){
32         sum[o]=a[l];
33         return;
34     }
35     int m=(l+r)/2;
36     build(ls,l,m);
37     build(rs,m+1,r);
38     sum[o]=sum[ls]+sum[rs];
39 }
40 
41 ll qu(int o,int l,int r,int ql,int qr){
42     if(l>=ql&&r<=qr)return sum[o];
43     if(l>qr||r<ql)return 0;
44     int m=(l+r)/2;
45     ll lsum=qu(ls,l,m,ql,qr);
46     ll rsum=qu(rs,m+1,r,ql,qr);
47     return lsum+rsum;
48 }
49 
50 void up(int o,int l,int r,int ql,int qr){
51     
52     if(sum[o]<=(r-l+1))return;
53 
54     if(l>qr||r<ql)return;
55     if(l==r){
56         sum[o]=sqrt(sum[o]);
57         return;
58     }
59     int m=(l+r)/2;
60     up(ls,l,m,ql,qr);
61     up(rs,m+1,r,ql,qr);
62     sum[o]=sum[ls]+sum[rs];
63 }
64 
65 int main(){
66     
67     int Case=0;
68     while(~scanf("%d",&n)){
69         for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
70 
71         Case++;
72         printf("Case #%d:\n", Case);
73         build(1,1,n);
74 
75         int q;
76         scanf("%d",&q);
77 
78 
79         while(q--){
80             int op,L,R;
81             scanf("%d%d%d",&op,&L,&R);
82             if(L>R)swap(L,R);
83             if(op==0){
84                 up(1,1,n,L,R);
85             }
86             else{
87                 
88                 printf("%lld\n",qu(1,1,n,L,R));
89                 //cout<<qu(1,1,n,L,R)<<endl;
90             }
91         }
92         printf("\n");
93     }
94         
95 
96 
97 }

 

   

标签:ll,int,线段,战列舰,hdu4027,区间,include,sum,define
From: https://www.cnblogs.com/ccsu-kid/p/18202857

相关文章

  • [动态规划] 区间 dp
    区间dp石子合并将区间长度\(len\)作为\(dp\)的阶段设\(f[l][r]\)表示把最初的第\(l\)堆到第\(r\)堆石子合并成一堆,需要消耗的最少体力。合并代价就是这两堆石子的质量和,这里可以用前缀和直接计算,设\(s[i]\)表示前\(i\)堆石子的质量和。状态转移方程:\[f[l][r]......
  • halcon xld线段中点、端点和角度的计算
    一、xld线段中点area_center_points_xld(Line4,Area,Row,Column)二、xld线段端点*xld转regiongen_region_contour_xld(LineContours,RegionLines,'filled')*提取区域轮骨skeleton(RegionLines,Skeleton)*获取轮骨端点junctions_skeleton(RegionLines,EndPoints......
  • 可持久化线段树
    经典的数据结构。权值线段树:维护一个序列,然后记下每个\(a_i\)的出现次数,相当于线段树维护桶。然后这样就可以轻而易举的求出\(1-n\)之间的第\(k\)小数了。原理类似于平衡数求\(rank.\)动态·可持久化下面考虑动态的权值线段树。\(l-r\)查询可以理解为第\(r\)个......
  • 洛谷 P2824 [HEOI2016/TJOI2016] 排序(二分,线段树)
    传送门解题思路据说是经典思路:把多次排序转化成二分+01序列。首先二分所求位置的数字是啥,将大于mid的数字变成1,将小于等于mid的数字变成0。这样在排序的时候就相当于统计区间里的1的个数(区间和),然后区间全部变成0或者1。也就是区间修改,区间求和,线段树可以实现。AC代码#inclu......
  • 雨天的尾巴(P4556 [Vani有约会] 雨天的尾巴 /【模板】线段树合并)
    1.题意简化N个点,形成一个树状结构。有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成所有发放后,每个点存放最多的是哪种物品。2.思路首先这道题肯定要用先建树,然后我们可以在树上的每个节点建一个权值线段树,考虑到空间问题(每个点都有1个权值......
  • # 2024_5_10 区间分配tric
    2024_5_10区间分配tric考虑这样一个问题,\(n\)个区间,给每个\([l,r]\)之间的点分配一个区间,要求每个区间可以分配给区间内的点,最多分配给一个点。考虑化简,对于两个同左端点的区间\([a,b],[a,c],b\leqc\),那么效果完全等价于\([a,b],[a+1,c]\)。经过这样的变化就不存在左端点相同......
  • 763. 划分字母区间
    给你一个字符串s。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是s。返回一个表示每个字符串片段的长度的列表。示例1:输入:s="ababcbacadefegdehijhklij"输出:[9,7,8]解释:划......
  • P4839 P 哥的桶 线段树+线性基
    P4839P哥的桶线段树+线性基题目链接题意:现在有\(n\)个桶,需要支持2种操作。\(1\)\(k\)\(x\):将一个价值为\(x\)的球放进\(k\)号桶。\(2\)\(l\)\(r\):求出在\(l\)号桶到\(r\)号桶之间拿球,价值异或和最大值。思路:单点修改,区间查询。可以想到用线段树维护......
  • P3842 [TJOI2007] 线段
    洛谷-题目链接[TJOI2007]线段提示我们选择的路线是(1,1)(1,6)(2,6)(2,3)(3,3)(3,1)(4,1)(4,2)(5,2)(5,6)(6,6)(6,4)(6,6)不难计算得到,路程的总长度是24。代码代码#include<bits/stdc++.h>usingnamespacestd;constintN=2e4+5......
  • 贪心:重叠区间问题
    leetcode452,435假设有intervals[][]这么一个二维数组,我们要找到其中的重叠区间个数:解题思路:分两种情况讨论即可:首先我们需要对区间进行一个排序,为了尽量让相邻的区间重叠,以便后续操作1.如果当前区间的左边界和上个区间的右边界不重合,那么这两个区间肯定是......