BZOJ3995:[SDOI2015]道路修建(线段树)[通俗易懂]

BZOJ3995:[SDOI2015]道路修建(线段树)

大家好,又见面了,我是你们的朋友全栈君。

Description

 某国有2N个城市,这2N个城市构成了一个2行N列的方格网。现在该国政府有一个旅游发展计划,这个计划需要选定L、R两列(L<=R),修建若干条专用道路,使得这两列之间(包括这两列)的所有2(R-L+1)个城市中每个城市可以只通过专用道路就可以到达这2(R-L+1)个城市中的任何一个城市。这种专用道路只能在同一行相邻两列的城市或者同一列的两个城市之间修建,且修建需要花费一定的费用。由于该国政府决定尽量缩减开支,因此政府决定,选定L、R后,只修建2(R-L+1)-1条专用道路,使得这些专用道路构成一个树结构。现在你需要帮助该国政府写一个程序,完成这个任务。具体地,该任务包含M个操作,每个操作的格式如下:
1.        C x0 y0 x1 y1 w:由于重新对第x0行第y0列的城市和第x1行第y1列的城市之间的情况进行了考察,它们之间修建一条专用道路的花费变成了w;
2.        Q L R:若政府选定的两列分别为L、R,询问政府的最小开支。

Input

 第一行,两个整数N、M。

第二行,N-1个整数,其中第i个整数表示初始时第1行第i列的城市和第1行第i+1列的城市之间修建一条专用道路的费用。
第三行,N-1个整数,其中第i个整数表示初始时第2行第i列的城市和第2行第i+1列的城市之间修建一条专用道路的费用。
第四行,N个整数,其中第i个整数表示初始时第1行第i列的城市和第2行第i列的城市之间修建一条专用道路的费用。
接下来的M行,每行一个操作。

Output

对于每个询问操作,输出一行,表示你计算出的政府的最小开支。

 

Sample Input

3 3
1 2
2 1
3 1 2
Q 1 3
C 1 2 2 2 3
Q 2 3

Sample Output

7
5

HINT

 对于全部的数据,1<=N, M<=60000,任何时刻任何一条专用道路的修建费用不超过10^4。

Solution

这个题真的非常恶心啊……
首先这个题一看就是线段树= =……因为想了想别的好像做不了
就上线段树然后强行讨论过了样例,结果0分
拍了一下发现我讨论的好像并不全= =……
后来我看到一篇和我一样强行讨论的题解,
才发现我讨论的有点少QAQ
https://www.cnblogs.com/maijing/p/4832745.html
上面博客里那位大爷讨论的挺详细的
不过我写的比他短将近一半

Code

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #define N (70000+100)
  5 using namespace std;
  6 
  7 struct node{
   
   int X[6];}Segt[N<<2];
  8 int n,m,a[N],L[3][N];
  9 int Form[20][5]=
 10 {
 11     {
   
   1,1,1},{
   
   1,2,2},{
   
   1,3,3},
 12     {
   
   1,4,4},{
   
   1,5,5},{
   
   2,1,2},
 13     {
   
   2,3,2},{
   
   2,5,4},{
   
   3,1,3},
 14     {
   
   3,3,3},{
   
   3,5,5},{
   
   4,1,4},
 15     {
   
   4,2,2},{
   
   4,4,4},{
   
   5,1,5},
 16     {
   
   5,2,3},{
   
   5,4,5},
 17 };
 18 
 19 node operator + (node x,node y)
 20 {
 21     node z;    
 22     memset(z.X,0x3f,sizeof(z));
 23     for (int i=0; i<=16; ++i)
 24         z.X[Form[i][2]]=min(z.X[Form[i][2]],x.X[Form[i][0]]+y.X[Form[i][1]]);
 25     return z;
 26 }
 27 
 28 node calc(int s)
 29 {
 30     node ans;
 31     ans.X[1]=L[1][s]+L[2][s];
 32     ans.X[2]=L[1][s]+L[2][s]+a[s]+a[s+1]-max(max(L[1][s],L[2][s]),max(a[s],a[s+1]));
 33     ans.X[3]=a[s+1]+min(L[1][s],L[2][s]);
 34     ans.X[4]=a[s]+min(L[1][s],L[2][s]);
 35     ans.X[5]=min(L[1][s],L[2][s]);
 36     return ans;
 37 }
 38 
 39 void Build(int now,int l,int r)
 40 {
 41     if (l==r)
 42     {
 43         Segt[now]=calc(l);
 44         return;
 45     }
 46     int mid=(l+r)>>1;
 47     Build(now<<1,l,mid);
 48     Build(now<<1|1,mid+1,r);
 49     Segt[now]=Segt[now<<1]+Segt[now<<1|1];
 50 }
 51 
 52 node Query(int now,int l,int r,int l1,int r1)
 53 {
 54     if (l1<=l && r<=r1)
 55         return Segt[now];
 56     int mid=(l+r)>>1;
 57     if (r1<=mid) return Query(now<<1,l,mid,l1,r1);
 58     if (l1>=mid+1) return Query(now<<1|1,mid+1,r,l1,r1);
 59     return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1);
 60 }
 61 
 62 void Update(int now,int l,int r,int x)
 63 {
 64     if (l==r)
 65     {
 66         Segt[now]=calc(l);
 67         return;
 68     }
 69     int mid=(l+r)>>1;
 70     if (x<=mid)    Update(now<<1,l,mid,x);
 71     if (x>mid)  Update(now<<1|1,mid+1,r,x);
 72     Segt[now]=Segt[now<<1]+Segt[now<<1|1];
 73 }
 74 
 75 int main()
 76 {
 77     scanf("%d%d",&n,&m);
 78     for (int i=1; i<=n-1; ++i) scanf("%d",&L[1][i]);
 79     for (int i=1; i<=n-1; ++i) scanf("%d",&L[2][i]);
 80     for (int i=1; i<=n; ++i) scanf("%d",&a[i]);
 81     
 82     Build(1,1,n-1);
 83     for (int i=1; i<=m; ++i)
 84     {
 85         char opt[2]; int x0,y0,x1,y1,k;
 86         scanf("%s",opt);
 87         if (opt[0]=='Q')
 88         {
 89             scanf("%d%d",&x0,&y0);
 90             if (x0==y0) printf("%d\n",a[x0]);
 91             else printf("%d\n",Query(1,1,n-1,x0,y0-1).X[2]);
 92         }
 93         if (opt[0]=='C')
 94         {
 95             scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&k);
 96             if (y0==y1)
 97             {
 98                 a[y0]=k;
 99                 if (y0!=1) Update(1,1,n-1,y0-1);
100                 if (y0!=n) Update(1,1,n-1,y0);
101             }
102             else
103             {
104                 L[x0][min(y0,y1)]=k;
105                 Update(1,1,n-1,min(y0,y1));
106             }
107         }
108     }
109 }

转载于:https://www.cnblogs.com/refun/p/8888092.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107568.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 后台开元模板 H-ui.admin

    后台开元模板 H-ui.admin

  • jediscluster 关闭 连接池_Redis——JedisCluster

    jediscluster 关闭 连接池_Redis——JedisClustersmart客户端实现原理(追求性能,不使用代理)从集群中选一个可运行节点,使用clusterslots初始化槽和节点映射。将clusterslots的结果映射到本地,为每个节点创建JedisPool。执行命令执行命令执行命令的过程简单来说,就是通过CRC16计算出key的槽,根据节点映射直接访问目标节点,如果出错,就随机挑选一个节点,通过moved重定向访问目标节点,并且重新初始化节点映射。好…

    2022年10月10日
  • python获取图片并储存图片_python用户输入矩形的长和宽

    python获取图片并储存图片_python用户输入矩形的长和宽1、opencv2、imageio3、matplotlib4、scipy#coding:utf-8importcv2importimageiofromscipyimportmiscfromPILimportImagefrommatplotlibimportpyplotaspltimage_path=”./images/000011.jpg”#使用pillow读取图…

  • pycharm调大字体快捷键_设置pycharm字体大小

    pycharm调大字体快捷键_设置pycharm字体大小一、pycharm字体放大的设置File—>setting—>Keymap—>在搜寻框中输入:increase —>IncreaseFontSize

  • java setscale_BigDecimal.setScale(int newScale, int roundingMode)方法实例「建议收藏」

    java setscale_BigDecimal.setScale(int newScale, int roundingMode)方法实例「建议收藏」java.math.BigDecimal.setScale(intnewScale,introundingMode)返回一个BigDecimal,其精度为指定值,其非精度值乘以或除以此BigDecimal的非精度值除以10,以保持其整体值。如果该精度是减少了操作中,未缩放的值必须被除(而不是乘),并且该值可以被改变。在这里,指定的舍入模式应用到除法。由于BigDecimal对象是不可变的,这…

    2022年10月20日
  • csgo所有开箱网站_csgo国外开箱网站

    csgo所有开箱网站_csgo国外开箱网站CSGO国内开箱网站大全收录incsgo官网,skinsdog官网,coolkaixiang官网,88steam官网,Box818官网,Piggycase官网,Yskins官网incsgo国内CSGO饰品皮肤开箱网站官方链接:www.incsgo.gg注册登录自动免费获得$1.00美金取回状态:直接取回**优惠码:**csgogo(充值使用csgogo可增加5%充值金额)skinsdog狗网CSGO饰品皮肤开箱网站可直接取回官方链接:skinsdog.cc.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号