有关数据结构的知识17.5.1清北

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<queue>
  5 #include<stack>
  6 #include<map>
  7 //#include<unordered_map>
  8
  9 using namespace std;
 10
 11 **********重载运算符*************
 12 struct rec
 13 {
 14     int a,b;
 15     bool operator<(const rec &c)const
 16     {
 17         if (a==c.a) return b>c.b;
 18         else return a>c.a;
 19     }
 20 }g,gg;
 21 ****************链表************
 22 int v[maxn],next[maxn],cnt;
 23
 24 void zou()链表移动
 25 {
 26     int p=1;
 27     int sum=0;
 28     while (p!=0)
 29     {
 30         sum+=v[p];
 31         p=next[p];
 32     }
 33 }
 34
 35 void charu(int p,int w)链表插入
 36 {
 37     cnt++;
 38     v[cnt]=w;
 39     next[cnt]=next[p];
 40     next[p]=cnt;
 41 }
 42 ************栈***队列***堆***********8
 43 int main()
 44 {
 45     g<gg;
 46     int x;
 47     queue<int> que;
 48     que.push(x);
 49     int y=que.front();
 50     que.pop();
 51     que.size();
 52
 53     stack<int> sta;
 54     sta.push(x);
 55     int z=sta.top();
 56     sta.pop();
 57     sta.size();
 58
 59     priority_queue<rec> heap;
 60     heap.push(x);
 61     int r=heap.top();
 62     heap.pop();
 63     heap.size();
 64 }
 65 *************并查集 ****************
 66 int f[maxn];
 67
 68 for (int a=1;a<=n;a++)
 69     f[a]=a;
 70
 71 int getf(int now)
 72 {
 73     if (f[now]==now) return now;
 74     else return f[now]=getf(f[now]);
 75 }
 76
 77 int merge(int p1,int p2)
 78 {
 79     f[getf(p1)]=getf(p2);
 80 }
 81
 82 bool same(int p1,int p2)
 83 {
 84     return getf(p1)==getf(p2);
 85 }
 86 ****************hash****************
 87 map<long long,int> ma;
 88 map<string,int>;
 89 map<rec,int>;
 90
 91 ma[num]=ma[num]+1;
 92 ma[num];
 93 ***************线段树************
 94 ***************递归**************
 95 int a[maxn];
 96
 97 int sum[maxn*4];
 98
 99 void update(int rt)
100 {
101     sum[rt]=sum[rt*2]+sum[rt*2+1];
102 }
103
104 void build(int l,int r,int rt)建立从l到r标号st
105 {
106     if (l==r)到最后节点
107     {
108         sum[rt]=a[l];
109         return;
110     }
111     int m=(l+r)/2;
112     //int m=(l+r)>>1;
113     build(l,m,rt*2);建立左边
114     //build(l,m,rt<<1);
115     build(m+1,r,rt*2+1);建立右边
116     //build(m+1,r,rt<<1|1);
117     ***********全部分离**********
118     update(rt);填入数
119 }
120 ***********修改
121 void modify(int l,int r,int rt,int p,int v)
122 {
123     if (l==r)进行到最后
124     {
125         sum[rt]=v;进行修改
126         return;
127     }
128     int m=(l+r)/2;
129     if (p<=m) modify(l,m,rt*2,p,v);
130     else modify(m+1,r,rt*2+1,p,v);全部分离
131     update(rt);将修改后的状态全部改变
132 }
133 ***********求从nowl到nowr的值
134 int query(int l,int r,int rt,int nowl,int nowr)
135 {
136     if (nowl<=l && r<=nowr) return sum[rt];此区间l到r被nowl和nowr完全包含住就返回此线段的值
137     int m=(l+r)/2;继续分离
138     int ans=0;
139     if (nowl<=m) ans+=query(l,m,rt*2,nowl,nowr);和左边有交集  询问左边
140     if (m<nowr) ans+=query(m+1,r,rt*2+1,nowl,nowr);和右边有交集  询问右边
141     return ans;
142 }
143
144 scanf("%d",&n);
145 for (int b=1;b<=n;b++)
146     scanf("%d",&a[b]);
147 build(1,n,1);
148 modify(1,n,1,p,v);
149 query(1,n,1,nowl,nowr);
150 *****************
151 notonlysuccess
152
153 *******************树状数组*********
154 简介:
155     对于一个数组求其l到r的值的和,即从l--r;利用分治(类似规定)算(2^lowbit(x)--r)+(l--r);再将2^lowbit(x)递归进行分解;
156     lowbit(x)是指将x转化为2进制后,从低位到高位第1个"1"的位置即第几位(从0开始数)例如;lowbit(6)=1;6的2进制为110,即2;
157     求[1,7]等价于     [7,7]        +           [1,6]
158              对应2^lowbit(7)--7          1--2^lowbit(7)
159     而[1,6]等价于     [4,5]        +          [1,4]
160               对应 2^lowbit(4)--4         1-- 2^lowbit(4);
161
162 **************树状数组*********
163 lb(x) = 2^lowbit(x)
164
165 int lb(int x)
166 {
167     return x&(-x);取出将x转换为3进制后最后一个1;例x  0001000,则-x 1111000即从最后一个1开始往前取反;然后进行与运算相同为1,不同为0
168 }
169
170 z : 树状数组
171 y : 数组
172
173 void modify(int p,int v)修改 将p位置的数改为v
174 {
175     int delta=v-y[p];将p后面的数都加上(更改的数-原来的数)
176     y[p]=v;更改
177     for (;p<=n;p+=lb(p))+= 2^lowbit(x)
178         z[p]+=delta;树状数组进行更改
179 }
180
181 int query(int p)询问
182 {
183     int ans=0;
184     for (;p;p-=lb(p))按照lb(p)的顺序进行
185         ans+=z[p];
186     return ans;
187 }
188 *****************树状数组伪***************
189 #include<iostream>
190 using namespace std;
191 int n,m,i,num[100001],t[200001],l,r;//num:原数组;t:树状数组
192 int lowbit(int x)
193 {
194     return x&(-x);
195 }
196 void change(int x,int p)//将第x个数加p
197 {
198     while(x<=n)
199     {
200         t[x]+=p;将树状数组中第x
201         x+=lowbit(x);
202     }
203     return;
204 }
205 int sum(int k)//前k个数的和
206 {
207     int ans=0;
208     while(k>0)
209     {
210         ans+=t[k];
211         k-=lowbit(k);
212     }
213     return ans;
214 }
215 int ask(int l,int r)//求l-r区间和
216 {
217     return sum(r)-sum(l-1);
218 }
219 int main()
220 {
221     cin>>n>>m;
222     for(i=1;i<=n;i++)
223     {
224         cin>>num[i];
225         change(i,num[i]);
226     }
227     for(i=1;i<=m;i++)
228     {
229         cin>>l>>r;
230         cout<<ask(l,r)<<endl;
231     }
232     return 0;
233 }
234 *************涂色************
235 for (int a=m;a>=1;a--)
236 {
237     for (int b=getf(l[a]);b<=r[a];b=getf(b+1))
238     {
239         if (!color[b]) ans[b]=color[b];
240         f[getf(b)]=getf(r[a]);
241     }
242 }
243 *************分块*****************
244 int s=sqrt(n);分成块的大小为sqrt(n);
245 for (int i=1;i<=n;i++)
246     belong[i]=(i-1)/s+1;belong[i]数组表示第i个数所在的块
247 int cnt=belong[n];一共有几块
248
249 for (int i=1;i<=cnt;i++)
250 {
251     sum[i]=add[i]=0;sum表示此时第i块的总值为几,add表示第i块添加的数的总和
252     if (i==cnt)防止最后一块不足s,size表示每一块的长度
253     {
254         if (n%s==0) size[i]=s;
255         else size[i]=n%s;
256     }
257     else size[i]=s;
258 }
259 for (int i=1;i<=n;i++)
260     sum[belong[i]]+=a[i];i所属的那一块的sum加上ai
261
262 int query(int l,int r)访问
263 {
264     int ans=0;
265     if (belong[l]==belong[r]) ans-=sum[belong[l]];此处为避免l与r属于同一块画图很好理解,此处不再解释
266     while (belong[l]==belong[l-1])
267     {
268         ans+=a[l]+add[belong[l]];因为l要++,所以l会遍历在从l到r的不整区间中所有的数,so要加a数组 **从左到第一个整区间
269         l++;
270     }
271     while (belong[r]==belong[r+1])**从最后一个整区间到最后
272     {
273         ans+=a[r]+add[belong[r]];
274         r--;
275     }
276     for (int i=belong[l];i<=belong[r];i++)加入所有整区间的数
277         ans+=sum[i];
278     return ans;
279 }
280
281 void modify(int l,int r,int v)修改
282 {
283     if (belong[l]==belong[r])属于同一分块
284     {
285         for (int i=l;i<=r;i++)so easy
286             a[i]+=v;
287         return;
288     }
289     while (belong[l]==belong[l-1])自此往下同上访问
290     {
291         a[l]+=v;
292         l++;
293     }
294     while (belong[r]==belong[r+1])
295     {
296         a[r]+=v;
297         r--;
298     }
299     for (int i=belong[l];i<=belong[r];i++)
300     {
301         add[i]+=v;
302         sum[i]+=size[i]*v;
303     }
304 }

相信你会收获很多**********

时间: 2024-10-12 14:35:57

有关数据结构的知识17.5.1清北的相关文章

清北夏令营考试day1

清北夏令营考试day1 送分题(songfen) Time Limit:1000ms   Memory Limit:128MB 题目描述: LYK喜欢干一些有挑战的事,比如说求区间最大子段和.它知道这个题目有O(n)的做法.于是它想加强一下. 也就是说,LYK一开始有n个数,第i个数字是ai,它找来了一个新的数字P,并想将这n个数字中恰好一个数字替换成P.要求替换后的最大子段和尽可能大. LYK知道这个题目仍然很简单,于是就扔给大家来送分啦~ 注:最大子段和是指在n个数中选择一段区间[L,R](

清北学堂2017NOIP冬令营入学测试 P4744 A’s problem(a)

清北学堂2017NOIP冬令营入学测试 P4744 A's problem(a) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算一次成绩.参与享优惠 描述 这是一道有背景的题目,小A也是一个有故事的人.但可惜的是这里纸张太小,小A无法把故事详细地说给大家听.可能小A自己也讲不清楚自己的故事,因为如果讲清了,也就没有这道题目了-- 小A的问题是这个样子,它找到了n份不同的工作,第i份工作每个月有ai的工资,每份工作需要小A每天

今我校——山东省著名高中——济南市历城区第二中学《清北学子经验交流会》感悟

放飞梦想,一起成长--历城二中清北学子经验交流会于今日9时在行政楼会议室隆重召开. 与会领导有:济南市教育局宣传科科长.高中部李矿水副校长.高三级部级部主任暨高中部副校长田庆民校长.全国生物奥赛金牌暨清华大学预录取的任雨同学.化学奥赛全国金牌被清华大学降至一本线录取的两位学长.数学奥赛被清华大学降至一本线录取的一位学长以及来自五湖四海的媒体朋友们,会议开场对他们的到来表达了热烈的欢迎.

五一清北总结——day1+day2

五一清北学习总结 ——day1+day2 一.排序 1.快速排序 O(nlogn)的排序,用sort可以快速完成,但是可以被卡,手写sort利用随机数可以避免被卡掉. 代码: void quick_sort(int *a, int l, int r) { swap(a[l], a[rand()*rand() % (r -l + 1) +l]); int tmp = a[l]; int l_ = l, r_ = r; while (l < r) { while (l < r) { if (a[r

清北押题班(1)

清北押题冲刺班Text1 T1 Count 问有几个无序二元组 $ (x ?, ?y) $ 满足 $ xy \equiv 1?(mod?P ) $ , $ 0 \leq x < P?, ?0 \leq y <P $ 解题思路: 你没看错,这是day1的T1,一道赤裸裸的数学题. Subtask 1:枚举 $ O(P^2) $ 个二元组,选出符合条件的,再去重: Subtask 2:可以发现模 $ P $ 意义下,一个数 x 有逆元,当且仅当 $ gcd(x, P) = 1 $ .并且如果 $

# 清北冬令营真题泛做

清北冬令营真题泛做 前言 这段时间为了准备冬令营把清北冬令营真题都做了一下.更个博回顾一下(免得你们老说我咕咕咕). 先写良心PKU的题再写THU的题, 主要是THU的题和PKU比起来真的毒瘤好多...... PKUWC2018 [PKUWC2018]Minimax 一个比较显然的暴力是归并排序,每次直接前后缀计算答案即可. 为啥不用线段树合并代替归并排序呢? 暴力线段树合并,合并的过程中顺便算一下即可,由于权值区间不交所以复杂度一个\(log\). [PKUWC2018]Slay the Sp

铁轨 清北学堂 线段树

铁轨 清北学堂 线段树 [题目描述] R 国的铁轨经常会进行重新修建. R 国是一个细长的国家,一共有 n 个城市排成一排,首都位于 1 号城市,相邻两个城市之间有铁路相连. 每次新建铁轨的时候,一定是从首都开始修建,直到某一个城市为止,这其间的铁路都会变成新版本的设 施,而旧设施会被拆除.然而,由于 R 国的工程师脑子不太好使,任意两种不同版本的铁路之间都无法连 接,因此必须要进行换乘. 现在给出你修建铁轨的操作,小 R 时不时第会想问你,如果在第 x 个城市到第 y 个城市之间随机选择一个

数据结构基础知识1

一. 理解并能快速.准确写出代码.(★★★★★) 1. 几种常见排序( 代码 ) 基于比较的排序算法: 下界是 nlgn 1.1 SelectionSort:每次选出最下的元素,放在当前循环最左边的位置. 1.2 BubbleSort:每次比较相邻的两个数,使得最大的数像气泡一样冒到最右边. 1. 3 InsertionSort:每次拿起一个数,插入到它左边数组的正确位置. 1.4 QuickSort:选择一个数,作为标准,小于它的放在左边,大于它的放在右边.并把它放在中间:递归地对左右子数组进

《计算机科学导论》之数据结构基础知识

<计算机科学导论(第二版)>  11章   数据结构 11.1  引言  1.为什么要使用数据结构? 尽管单变量在程序设计语言中被大量使用,但是它们不能有效地解决复杂问题.此时考虑使用数据结构. 2.数据结构是什么? 数据结构是相互之间存在一种或多种特定关系的数据元素的集合. 3.三种数据结构 数组: 记录; 链表: 大多的编程语言都隐式实现了前两种,而第三种则通过指针和记录来模拟. 11.2  数组 1.为什么使用数组? 为了处理大量的数据,需要一个数据结构,如数组.当然还有其他的数据结构.