【模拟8.10】Weed(线段树)
考试只好随便骗骗分过去啦啦啦.....
正解是玄学线段树:
以每个操作为叶子节点,我们定义几个变量ce表示层数,h表示高度,add表示所减的层数
那么问题转化为单点修改的问题输出直接是根节点答案
但是我们发现合并区间很毒瘤
我们分两种情况:
设L为左儿子,R为右儿子。
1.T[L].ce<T[R].add 显然我们只需O(1)修改。
2.T[L].ce>T[R].add 我们需要将左子树后面的add个减去,我们自然想到了类似平衡树的
查找后缀的操作,于是肝.....
开始时我的query计算有多少减去,但是WA20
因为少考虑一种情况:
你的左子树中假设左子树根结点为K,左儿子Lson,右儿子Rson
右儿子中也可能有剩余的add,
那么我们直接发现右面不够查左面是不行的.........
听了toot大神的建议,我改为了查询还有多少留下
if(t[k*2+1].ce<ceng)
{
qq_sum+=t[k*2+1].h;
query_sum(k*2,l,mid,ceng-t[k*2+1].ce+t[k*2+1].add);
}
当发现右端点少时,向左端点转移还需要减去靠右的add个
然后就没啥了,注意细节就好
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<string>
5 #include<set>
6 #include<map>
7 #define int long long
8 #define MAXN 1000010
9 using namespace std;
10 int read()
11 {
12 int x=0;char c=getchar();
13 while(c<'0'||c>'9')c=getchar();
14 while(c>='0'&&c<='9')
15 {
16 x=(x<<1)+(x<<3)+(c^48);
17 c=getchar();
18 }
19 return x;
20 }
21 struct node{int ce,h,add,l,r;}t[MAXN*2];
22 int qq_sum;int m,q;
23 int orz[MAXN],mm[MAXN];
24 void query_sum(int k,int l,int r,int ceng)
25 {
26 if(l==r)
27 {
28 if(ceng!=0)qq_sum+=t[k].h;
29 return ;
30 }
31 int mid=(l+r)>>1;
32 //printf("k=%lld l=%lld r=%lld\n",k,l,r);
33 if(t[k*2+1].ce<ceng)
34 {
35 qq_sum+=t[k*2+1].h;
36 query_sum(k*2,l,mid,ceng-t[k*2+1].ce+t[k*2+1].add);
37 }
38 else
39 {
40 query_sum(k*2+1,mid+1,r,ceng);
41 }
42 return ;
43 }
44 void updata(int k)//左儿子是否保存
45 {
46 int r=k*2+1;
47 int l=k*2;
48 //printf("--------\nupdata k=%lld %lld %lld\n",k,l,r);
49 // t[k].ce=t[l].ce+t[r].ce;
50 // t[k].h=t[l].h+t[r].h;
51 // t[k].add=t[l].add+t[r].add;
52 if(t[l].ce>t[r].add)
53 {
54 t[k].ce=t[l].ce+t[r].ce-t[r].add;
55 qq_sum=0;
56 query_sum(l,t[l].l,t[l].r,t[r].add);
57 t[k].h=t[l].h+t[r].h-qq_sum;
58 t[k].add=t[l].add;
59 //printf("--t[k].ce=%lld t[k].h=%lld add=%lld\n",t[k].ce,t[k].h,t[k].add);
60 }
61 else
62 {
63 t[k].h=t[r].h;
64 t[k].ce=t[r].ce;
65 t[k].add=t[r].add+t[l].add-t[l].ce;
66 //printf("t[k].ce=%lld t[k].h=%lld add=%lld\n",t[k].ce,t[k].h,t[k].add);
67 }
68 //printf("-----------\n");
69 return ;
70 }
71 void build(int k,int l,int r)
72 {
73 t[k].l=l;t[k].r=r;
74 if(l==r)
75 {
76 orz[l]=read();mm[l]=read();
77 if(orz[l]==0)
78 {
79 t[k].ce=1;t[k].h=mm[l];
80 //printf("t[%lld].ce=%lld t[%lld].h=%lld\n",k,t[k].ce,k,t[k].h);
81 }
82 else
83 {
84 t[k].add=mm[l];
85 //printf("t[%lld].add=%lld\n",k,t[k].add);
86 }
87 return ;
88 }
89 int mid=(l+r)>>1;
90 build(k*2,l,mid);
91 build(k*2+1,mid+1,r);
92 updata(k);
93 }
94 void F_add(int k,int l,int orzz,int x)
95 {
96 if(t[k].l==t[k].r)
97 {
98 t[k].add=0;t[k].ce=0;t[k].h=0;
99 if(orzz==0)
100 {
101 t[k].ce=1;
102 t[k].h=x;
103 //printf("t[%lld].ce=%lld t[%lld].h=%lld\n",k,t[k].ce,k,t[k].h);
104 }
105 else
106 {
107 t[k].add=x;
108 //printf("t[%lld].add=%lld\n",k,t[k].add);
109 }
110 return ;
111 }
112 int mid=(t[k].l+t[k].r)>>1;
113 if(l<=mid)F_add(k*2,l,orzz,x);
114 else F_add(k*2+1,l,orzz,x);
115 updata(k);
116 }
117 signed main()
118 {
119 //freopen("text.in","r",stdin);
120 // freopen("kkk.out","w",stdout);
121 m=read();q=read();
122 //printf("build\n");
123 build(1ll,1ll,m);
124 //printf("t[1].h=%lld\n",t[1ll].h);
125 for(int i=1;i<=q;++i)
126 {
127 int x,y,z;
128 x=read();y=read();z=read();
129 F_add(1,x,y,z);
130 printf("%lld\n",t[1].h);
131 }
132 }
附上对拍
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5 int c=0;
6 while(true)
7 {
8 system("./pai");//puts("ran work out");
9 system("./b");//puts("ac work out");
10 system("./kkk");//puts("kx work out");
11 if(system("diff -b -B b.out kkk.out"))
12 {
13 puts("WA");
14 return 0;
15 }
16 cout<<++c<<" ";
17 puts("AC");
18 }
19 return 0;
20 }
21 /*
22 g++ pai.cpp -o pai
23 ./pai
24 g++ b.cpp -o b
25 ./b
26 g++ kkk.cpp -o kkk
27 ./kkk
28 g++ ran.cpp -o ran
29 ./ran
30 */
随机数据生成
1 #include<bits/stdc++.h>
2 using namespace std;
3 int random(int m)
4 {
5 return (long long)rand()*rand()%m;
6 }
7 int judge()
8 {
9 int x=rand();
10 if(x%2)return 1;
11 else return 0;
12 }
13 pair<int,int>e[100000];
14 map<pair<int,int>,bool>h;
15 int main()
16 {
17 freopen("text.in","w",stdout);
18 srand((unsigned)time(0));
19 int n=random(7)+1;
20 int m=10;
21 int q=10;
22 printf("%d %d\n",m,q);
23 for(int i=1;i<=m;++i)
24 {
25 printf("%d %d\n",judge(),random(10)+1);
26 }
27 for(int i=1;i<=q;++i)
28 {
29 printf("%d %d %d\n",random(m)+1,judge(),random(10)+1);
30 }
31 return 0;
32 }
【模拟8.10】Weed(线段树)的更多相关文章
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- 【10.6校内测试】【小模拟】【hash+线段树维护覆盖序列】
一开始看到题就果断跳到T2了!!没想到T2才是个大坑,浪费了两个小时QAQ!! 就是一道小模拟,它怎么说就怎么走就好了! 为什么要用这么多感叹号!!因为统计答案要边走边统计!!如果每个数据都扫一遍20 ...
- 2018.10.26 NOIP模拟 图(最小生成树+线段树合并)
传送门 首先最开始说的那个一条路径的权值就是想告诉你两个点之间的贡献就是瓶颈边的权值. 那么肯定要用最小生成树算法. 于是我考场上想了30min+30min+30min+的树形dpdpdp 发现转移是 ...
- 2018.10.02 NOIP模拟 序列维护(线段树+广义欧拉定理)
传送门 一道比较好的线段树. 考试时线性筛打错了于是弃疗. 60分暴力中有20分的快速幂乘爆了于是最后40分滚粗. 正解并不难想. 每次区间加打懒标记就行了. 区间查询要用到广义欧拉定理. 我们会发现 ...
- Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]
洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...
- 【Foreign】Weed [线段树]
Weed Time Limit: 20 Sec Memory Limit: 512 MB Description 从前有个栈,一开始是空的. 你写下了 m 个操作,每个操作形如 k v : 若 k ...
- BZOJ 1920 Luogu P4217 [CTSC2010]产品销售 (模拟费用流、线段树)
题目链接 (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=1920 (luogu) https://www.luogu.org/prob ...
- BZOJ 5326 [JSOI2017]博弈 (模拟费用流、线段树)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5326 题解 终于成为第8个A掉这题的人--orz tzw神仙早我6小时 本以为这东西常数 ...
- BZOJ 3836 Codeforces 280D k-Maximum Subsequence Sum (模拟费用流、线段树)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=3836 (Codeforces) http://codeforces.com ...
随机推荐
- linux中定时运行php(每分钟执行一次为例)
注:使用Crontab定时执行php脚本文件 1. 安装crontab yum install crontabs 说明:/sbin/service crond start //启动服务/sbin/se ...
- Java常用类详解
目录 1. String类 1.1 String的特性 1.2 String字面量赋值的内存理解 1.3 String new方式赋值的内存理解 1.4 String 拼接字面量和变量的方式赋值 1. ...
- centos7安装es6.4.0
一.首先进入到opt文件夹cd opt二.然后下载es安装包wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearc ...
- JS数组的操作方法汇总
数组的增删 push():添加到最后 pop():取出最后一个 shift():取出第一个 unshift():添加到第一个 splice() : 返回删除的数组,如果没有则为空数组,会改变原数组.可 ...
- RHEL高级磁盘管理—Stratis
2. Stratis 本地存储管理工具,通过Stratis可以便捷的使用Thin Provisioning.Snapshots.Pool-based的管理和监控等高级存储功能. Stratis 基于x ...
- debian配置---->/etc/apt/sources.list apt基本源设置指南
yum或apt基本源设置指南 关于: 管理Linux服务器的运维或开发人员经常需要安装软件,最常用方式应该是通过Linux系统提供的包管理工具来在线安装,比如centos的yum,ubuntu或d ...
- Could not open device at /dev/ipmi0
Could not open device at /dev/ipmi0 分类: LINUX 2013-09-02 17:01:37 Could not open device at /dev/ip ...
- 10.13 nc:多功能网络工具
nc命令 是一个简单.可靠.强大的网络工具,它可以建立TCP连接,发送UDP数据包,监听任意的TCP和UDP端口,进行端口扫描,处理IPv4和IPv6数据包. 如果系统没有nc命令,那么可以手 ...
- Module not found: Error: Can't resolve 'less-loader' in ' xxx' (Day_40)
1. 错误代码: 2. 解决方法: 删除项目文件夹下的node_modules文件夹 执行npm install命令
- Jquery 常用方法及实例(Day_15)
想要做一件事,永远都不要怕晚.只要你开始做了,就不晚. 而若是你不开始,仅仅停留在思考.犹豫甚至焦虑的状态,那就永远都是零. mouseover() / mouserout() 当鼠标进入 / 离开某 ...