-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
1644 lines (1550 loc) · 77.1 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>对学委工作的建议</title>
<url>/2022/04/10/----10/</url>
<content><![CDATA[]]></content>
</entry>
<entry>
<title>位运算</title>
<url>/2022/04/07/----7/</url>
<content><![CDATA[<h2 id="位运算"><a href="#位运算" class="headerlink" title="位运算"></a>位运算</h2><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220407135412.png"><br>解:</p>
<pre><code>负数也可以算
#include<iostream>
using namespace std;
int n,i,a[100005],k,x;
int check(int x){
int res=0;
while(x!=0){
x=x&(x-1);
res++;
}
return res;
}
int main(){
cin>>n;
while (n--) {
k=0;
cin>>x;
cout<<check(x);
}
return 0;
}
</code></pre>
<p>&& </p>
<pre><code>#include<iostream>
using namespace std;
int lowbit(int x){
return x&(-x);
}
int main(){
int x;
cin>>x;
int res=0;
while (x!=0) {
x-=lowbit(x);
res++;
}
cout<<res<<" ";
return 0;
}
</code></pre>
]]></content>
</entry>
<entry>
<title>单调栈</title>
<url>/2022/04/07/----8/</url>
<content><![CDATA[<h2 id="单调栈"><a href="#单调栈" class="headerlink" title="单调栈"></a>单调栈</h2><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220407150929.png"><br>解:</p>
<pre><code>#include<iostream>
#include<vector>
using namespace std;
vector<int >a;
int main(){
int n;
cin>>n;
while (n--) {
int x;
scanf("%d",&x);
if(a.size()==0){
cout<<"-1 ";
a.push_back(x);
}
else if(a.back()<x){
cout<<a.back()<<" ";
a.push_back(x);
}
else {
while (a.back()>=x&&a.size()!=0) {
a.pop_back();
}
if(a.size()==0)cout<<"-1 ";
else cout<<a.back()<<" ";
a.push_back(x);
}
}
return 0;
}
</code></pre>
<p>&&</p>
<pre><code>#include <iostream>
using namespace std;
const int N = 100010;
int stk[N], tt;
int main()
{
int n;
cin >> n;
while (n -- )
{
int x;
scanf("%d", &x);
while (tt && stk[tt] >= x) tt -- ;//如果栈顶元素大于当前待入栈元素,则出栈
if (!tt) printf("-1 ");//如果栈空,则没有比该元素小的值。
else printf("%d ", stk[tt]);//栈顶元素就是左侧第一个比它小的元素。
stk[ ++ tt] = x;
}
return 0;
}
</code></pre>
<p>思路:<br><img src="https://img-blog.csdnimg.cn/20201211221031165.gif#pic_center"></p>
<hr>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220407155839.png"><br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220407155854.png"><br>解:</p>
<pre><code>#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int N=1000010;
int a[N],q[N],hh,tt=-1;
int main(){
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(i-k+1>q[hh])++hh;
while(hh<=tt&&a[i]<=a[q[tt]])tt--;
q[++tt]=i;
if(i+1>=k)cout<<a[q[hh]]<<" ";
}
cout<<endl;
hh=0;
tt=-1;
for(int i=0;i<n;i++){
if(i-k+1>q[hh])++hh;
while(hh<=tt&&a[i]>=a[q[tt]])--tt;
q[++tt]=i;
if(i+1>=k)cout<<a[q[hh]]<<" ";
}
return 0;
}
</code></pre>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220407155944.png"></p>
]]></content>
</entry>
<entry>
<title>JavaWeb实验二操作笔记</title>
<url>/2022/03/20/JavaWeb%E5%AE%9E%E9%AA%8C%E4%BA%8C%E6%93%8D%E4%BD%9C%E7%AC%94%E8%AE%B0/</url>
<content><![CDATA[<h1 id="JavaWeb实验二操作笔记"><a href="#JavaWeb实验二操作笔记" class="headerlink" title="JavaWeb实验二操作笔记"></a>JavaWeb实验二操作笔记</h1><pre><code>writer:宋丁沣
</code></pre>
<h3 id="1、创建一个动态web应用"><a href="#1、创建一个动态web应用" class="headerlink" title="1、创建一个动态web应用"></a>1、创建一个动态web应用</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404192712.png"><br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404192720.png"></p>
<h3 id="2、将两个html文件集成到webContent目录下"><a href="#2、将两个html文件集成到webContent目录下" class="headerlink" title="2、将两个html文件集成到webContent目录下"></a>2、将两个html文件集成到webContent目录下</h3><pre><code>注意将html文件名改为jsp,同时将代码中的html改为jsp
</code></pre>
<h3 id="3、创建一个Emp实体Bean"><a href="#3、创建一个Emp实体Bean" class="headerlink" title="3、创建一个Emp实体Bean"></a>3、创建一个Emp实体Bean</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404192731.png"></p>
<p>先定义好参数 </p>
<pre><code>package edu.hue.jk.db;
import java.sql.*;
public class Emp {
private int empno;
private String ename;
private Date hiredate;
}
</code></pre>
<p> 再将方法定义出来<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404192814.png"></p>
<h3 id="4、在两个jsp文件中引入Emp,用以替换之前的静态代码"><a href="#4、在两个jsp文件中引入Emp,用以替换之前的静态代码" class="headerlink" title="4、在两个jsp文件中引入Emp,用以替换之前的静态代码"></a>4、在两个jsp文件中引入Emp,用以替换之前的静态代码</h3><pre><code><%@ page import="java.sql.Date" %>
<%@ page import="edu.hue.jk.db.Emp" %>
----------------------------------------
<%
Emp e1 = new Emp();//定义一个对象
e1.setEmpno(1);//设置该对象的学号
e1.setEname("Tom");//设置该对象的姓名
e1.setHiredate(Date.valueOf("2018-09-01"));//设置该对象的信息,注意:valueOf中的O要大写
%>
-----------------------------------------
<td><%=e1.getEmpno() %></td>
<td><%=e1.getEname() %></td>
<td><%=e1.getHiredate() %></td>
//获取值
</code></pre>
<h3 id="实验2完成"><a href="#实验2完成" class="headerlink" title="实验2完成"></a>实验2完成</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404192826.png"></p>
<p>emp_list_jsp 完整代码</p>
<pre><code><%@ page import="java.sql.Date" %>
<%@ page import="edu.hue.jk.db.Emp" %>
<html>
<head>
</head>
<body>
<%
Emp e1 = new Emp();
e1.setEmpno(1);
e1.setEname("Tom");
e1.setHiredate(Date.valueOf("2018-09-01"));
Emp e2 = new Emp();
e2.setEmpno(2);
e2.setEname("Timo");
e2.setHiredate(Date.valueOf("2019-08-02"));
%>
<table border="1" width="80%" align="center" height="100">
<tr>
<td>
empno
</td>
<td>
ename
</td>
<td>
hiredate
</td>
<td>
operation
</td>
</tr>
<tr>
<td><%=e1.getEmpno() %></td>
<td><%=e1.getEname() %></td>
<td><%=e1.getHiredate() %></td>
<td>
<a href="emp_edit.jsp">edit</a>
<a href="delete">del</a>
</td>
</tr>
<tr>
<td><%=e2.getEmpno() %></td>
<td><%=e2.getEname() %></td>
<td><%=e2.getHiredate() %></td>
<td>
<a href="emp_edit.jsp">edit</a>
<a href="delete">del</a>
</td>
</tr>
<tr>
<td>
<a href="insert">add</a>
</td>
<td>
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
</body>
</html>
</code></pre>
]]></content>
</entry>
<entry>
<title>算法笔记</title>
<url>/2022/04/08/----9/</url>
<content><![CDATA[<h2 id="算法笔记"><a href="#算法笔记" class="headerlink" title="算法笔记"></a>算法笔记</h2><p>1、判定质数:</p>
<pre><code>一般做法:
bool is_prime(long long int x)//注意判定质数时全部开long long
{
if(x<2)return 0;
for(long long int i=2;i*i<=x;i++)//注意范围i*i<=n即可
{
if(x%i==0)return 0;
}
return 1;
}
质数筛:线性筛
void get_primes(int n)//每个质数乘一遍自己前面的质数,这样就能保证每个合数只被自己的最小质因子排除
{
for(int i = 2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i;
for(int j=0;primes[j]*i<=n;j++)
{
st[primes[j]*i] = true ;
if(i % primes[j] == 0) break ;
}
}
}
</code></pre>
<p>2、分解质因数<br>根据:<img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408190953.png"></p>
<p>重复除于2、3、5、7 …<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408191122.png"></p>
<p>3、求约数个数<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408193314.png"></p>
<p>根据:</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408193353.png"></p>
<pre><code>while(n--)
{
int x;
cin>>x;
for(int i=2;i<=x/i;i++)
{
while(x%i==0)
{
x=x/i;
primes[i]++;
}
}
if(x>1)primes[x]++;
}
long long res=1;
for(auto it:primes)res=res*(it.second+1)%(int)(1e9+7);
</code></pre>
<p>3、约数之和</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408193640.png"></p>
<p>4、最大公约数</p>
<pre><code>int gcd(int a ,int b)
{
return b?gcd(b,a%b):a;
}
</code></pre>
<p>5、快速幂</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408194538.png"></p>
<pre><code>while(n--)
{
cin>>a>>b>>p;
long long int res=1%p;
while(b)
{
if(b&1)res=res*a%p;
b>>=1;
a=a*a%p;
}
cout<<res<<endl;
}
</code></pre>
<p>6、快速找第几小个数:</p>
<pre><code> nth_element(a,x,a+n);
只改变第x位的数,其他数不改变
</code></pre>
<p>7、逆序对的数量(归并排序)</p>
<pre><code>要求结果的题记得加long long
void merge_sort(int q[],int l,int r){
if(l>=r)return ;
int mid=(r+l)>>1;
merge_sort(q, l, mid);
merge_sort(q, mid+1,r);//注意这里mid+1
int i=l,j=mid+1,k=0;//i,j是双指针,初始状态分别指向每一块中第一个数
while(i<=mid&&j<=r){
if(q[i]<=q[j])tmp[k++]=q[i++];//<=
else {
tmp[k++]=q[j++];
ans+=(mid-i+1);//应该减去i,不然会重复减
}
}
while(i<=mid)tmp[k++]=q[i++];
while(j<=r)tmp[k++]=q[j++];
for(int i=l,k=0;i<=r;i++,k++)q[i]=tmp[k];
}
</code></pre>
<p>8、在升序中找某个数存在的位置范围</p>
<pre><code>二分查找:
int k=lower_bound(a,a+n, l)-a;
第一个大于或者等于该数的地址
如果不存在则判断a【k】是否等于该值
int h=upper_bound(a,a+n,l)-a-1;
第一个大于该数的地址
</code></pre>
<p>9、答案一定在某个范围</p>
<pre><code>二分查找:
// 确定边界值
double l = -100000, r = 100000;
// 注意循环条件处理精度问题
while (r - l > 1e-8) {
// 步骤 A: 找中间值
double mid = (l + r) / 2;
// 步骤 B: 判断
if (mid * mid * mid < x) l = mid;
else r = mid;
}
</code></pre>
<p>10、在一个区间加上一个值(差分)</p>
<pre><code>差分矩阵可以把第一个数连接到上一排的最后一个数上
if(j!=1)s[i][j]=a[i][j]-a[i][j-1];
else s[i][j]=a[i][j]-a[i-1][m];
</code></pre>
<p>11、最长连续不重复子序列</p>
<pre><code> for(int i=0,j=0;i<n;i++)
{
b[a[i]]++;/
while(b[a[i]]>1)b[a[j++]]--;
maxl=max(maxl,i-j+1);
}
</code></pre>
<p>12、判断A序列是否为B的子序列</p>
<pre><code> for(int j=0;j<m;j++)
if(i<n&&a[i]==b[j])i++;
if(i==n)cout<<"Yes"<<endl;
</code></pre>
<p>13、判断x的二进制1的个数</p>
<pre><code>int check(int x){
int res=0;
while(x!=0){
x=x&(x-1);//或者x-=x&(-x)
res++;
}
return res;
}
</code></pre>
<p>14、输出每个数左边第一个比他小的数(单调栈)<br><img src="https://img-blog.csdnimg.cn/20201211221031165.gif#pic_center"></p>
<p>15、滑动窗口</p>
<pre><code>if(i-k+1>q[hh])++hh;//q【】储存的是坐标
while(hh<=tt&&a[i]<=a[q[tt]])tt--;
q[++tt]=i;
if(i+1>=k)cout<<a[q[hh]]<<" ";
</code></pre>
<p>16、询问一个字符串在集合中出现了多少次(Trie字符串统计)<br> 最大异或值,将每个数按照二进制储存在树中</p>
<pre><code>void insert(char *str)
{
int p = 0; //类似指针,指向当前节点
for(int i = 0; str[i]; i++)
{
int u = str[i] - 'a'; //将字母转化为数字
if(!son[p][u]) son[p][u] = ++idx; //该节点不存在,创建节点
p = son[p][u]; //使“p指针”指向下一个节点
}
cnt[p]++; //结束时的标记,也是记录以此节点结束的字符串个数
}
int query(char *str)
{
int p = 0;
for(int i = 0; str[i]; i++)
{
int u = str[i] - 'a';
if(!son[p][u]) return 0; //该节点不存在,即该字符串不存在
p = son[p][u];
}
return cnt[p]; //返回字符串出现的次数
}
</code></pre>
<p>17、并查集</p>
<pre><code>int find(int x)
{
if(p[x]!=x)p[x]=find(p[x]);
return p[x];
}
if(op[0]=='M')p[find(a)]=find(b);
else
{
if(find(a)==find(b))cout<<"Yes\n";
else cout<<"No\n";
}
</code></pre>
<p>18、哈希表</p>
<pre><code>int find(int x) {
int t = (x % N + N) % N;
while (h[t] != null && h[t] != x) {
t++;
if (t == N) {
t = 0;
}
}
return t; //如果这个位置是空的, 则返回的是他应该存储的位置
}
</code></pre>
<p>19、两个区间所包含的字符串子串是否完全相同(字符串哈希)</p>
<pre><code>一定要开longlong
ULL query(int l,int r){
return h[r] - h[l-1]*p[r-l+1];
}
//字符串从1开始编号,h[1]为前一个字符的哈希值
p[0] = 1;
h[0] = 0;
for(int i=0;i<n;i++){
p[i+1] = p[i]*P;
h[i+1] = h[i]*P +x[i]; //前缀和求整个字符串的哈希值
}
</code></pre>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408225059.png"></p>
<p>20、一共多少种情况(dfs)</p>
<ol>
<li>先判断最终情况,遍历输出</li>
<li>for循环遍历</li>
<li>根据各种情况,设置递归下一步的条件</li>
<li>st[x]=1;标记</li>
<li>fun(u+1)</li>
<li>st[x]=0;还原<br>```<br>一串数字的全排列</li>
</ol>
<p>void dfs(int u)<br>{<br> if(u > n)//数字填完了,输出<br> {<br> for(int i = 1; i <= n; i++)//输出方案<br> cout << path[i] << “ “;<br> cout << endl;<br> }</p>
<pre><code>for(int i = 1; i <= n; i++)//空位上可以选择的数字为:1 ~ n
{
if(!state[i])//如果数字 i 没有被用过
{
path[u] = i;//放入空位
state[i] = 1;//数字被用,修改状态
dfs(u + 1);//填下一个位
state[i] = 0;//回溯,取出 i
}
}
</code></pre>
<p>}</p>
<p>&&</p>
<p>next_permutation,这个函数其实求的是这个排列的下一个排列,若以是最后一个排列,就返回false</p>
<pre><code>for(int i=1;i<=n;i++)a[i]=i,printf("%d ",i);
while(next_permutation(a+1,a+1+n)){
printf("\n");
for(int i=1;i<=n;i++)printf("%d ",a[i]);
}
</code></pre>
<pre><code>
在处理斜线的时候
bool dg【N】,udg【N】
对角线 dg[x+y],dg[i]代表不同斜率的斜线
反对角线udg[n−u+i],dg[i]代表不同斜率的反斜线
下标 x+y
和 n−x+y
表示的是截距
y=kx+b
当同一斜率时dg【num】,num是相同的。
21、在图上至少需要移动多少次。(bfs)
1. 创建一个queue
2. q.push({0,0})摁进初始状态
3. 遍历队列(while队列不为空)
4. 将队列第一个值取出来复制 t=q.front()
5. 将第一个值丢掉 q.pop()
6. for循环四个方向
7. 定义新的坐标变量,int xx=t.first+dx[i]
8. if(xx>=0&&xx<边界&&yy>=0&&yy<边界&&当前路没走过&&当前距离为空)
9. 距离在d[t.first][t.second]基础上加1
10. 将这个点推进队列
</code></pre>
<p>int bfs(){<br> queue<PII>q;<br> q.push({0,0});<br> while (!q.empty()) {<br> auto t=q.front();<br> q.pop();<br> for(int i=0;i<4;i++){<br> int x=t.first+dx[i];<br> int y=t.second+dy[i];<br> if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]==0&&d[x][y]==0){<br> d[x][y]=d[t.first][t.second]+1;<br> q.push({x,y});<br> }<br> }<br> }<br> return d[n-1][m-1];<br>}</p>
<pre><code>
22、二维有顺序矩阵的移动(降维)
![](https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220408232353.png)
将内容转换为一维字符串
然后再进行正常的bfs
queue<string>q;
距离用unordered_map<string ,int>dist;
!d.count(t),如果找不到t对象,t没有被遍历过
23、无边数限制求最短路(Dijkstra)
1. 初始化头指针为-1
2. 建立邻接表
3. 初始化dist为无穷大
4. 设置初始距离,序号1的点为0
5. 定义优先队列 priority_queue<PII,vector<PII>,greater<PII> >heap;
6. 将初始点推进。heap.push({0,1})
7. 遍历队列(while队列不为空)
8. 将第一个值取出,t=heap.top(),ver=t.second(),distance=t.first
9. 出列第一个值
10. 如果这个值被遍历过就continue
11. 否则那就标记
12. 循环这个序号 for(int i=h[ver],i!=-1;i=ne[i])int j=e[i];
13. 如果j到1的距离大于点到t的距离加上w[i]
14. 更新dist[j],并将该点推进队列。
</code></pre>
<p>void add(int x, int y, int c)<br>{<br> w[idx] = c; // 有重边也不要紧,假设1->2有权重为2和3的边,再遍历到点1的时候2号点的距离会更新两次放入堆中<br> e[idx] = y; // 这样堆中会有很多冗余的点,但是在弹出的时候还是会弹出最小值2+x(x为之前确定的最短路径),并<br> ne[idx] = h[x]; // 标记st为true,所以下一次弹出3+x会continue不会向下执行。<br> h[x] = idx++;<br>}</p>
<p>int dijkstra()<br>{<br> memset(dist, 0x3f, sizeof(dist));<br> dist[1] = 0;<br> priority_queue<PII, vector<PII>, greater<PII>> heap; // 定义一个小根堆<br> // 这里heap中为什么要存pair呢,首先小根堆是根据距离来排的,所以有一个变量要是距离,其次在从堆中拿出来的时<br> // 候要知道知道这个点是哪个点,不然怎么更新邻接点呢?所以第二个变量要存点。<br> heap.push({ 0, 1 }); // 这个顺序不能倒,pair排序时是先根据first,再根据second,这里显然要根据距离排序<br> while(heap.size())<br> {<br> PII k = heap.top(); // 取不在集合S中距离最短的点<br> heap.pop();<br> int ver = k.second, distance = k.first;</p>
<pre><code> if(st[ver]) continue;
st[ver] = true;
for(int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i]; // i只是个下标,e中在存的是i这个下标对应的点。
if(dist[j] > distance + w[i])
{
dist[j] = distance + w[i];
heap.push({ dist[j], j });
}
}
}
if(dist[n] == 0x3f3f3f3f) return -1;
else return dist[n];
</code></pre>
<p>}</p>
<pre><code>
24、任意点对任意点的最短路 弗洛伊德
注意:用稠密图储存时,g[i][j]=min(g[i][j],w[i]),避免重边和自环
1. 将i=j的点赋值为0,自己跟自己的距离是0
2. 存图
3. 开始遍历,一个k作为中间站,一个i和一个j作为起点和终点,一直更新d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
25、稠密图求最小生成树(prim)
和狄杰斯特拉算法类似,每次取点需要将边权相加
</code></pre>
<p>int Prim()<br>{<br> memset(vis, false, sizeof vis);<br> int sum = 0, cnt = 0;<br> priority_queue<PII, vector<PII>, greater<PII>> q;<br> q.push({0, 1});</p>
<pre><code>while (!q.empty())
{
auto t = q.top();
q.pop();
int ver = t.second, dst = t.first;
if (vis[ver]) continue;
vis[ver] = true, sum += dst, ++cnt;
for (int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i];
if (!vis[j]) {
q.push({w[i], j});
}
}
}
if (cnt != n) return INF;
return sum;
</code></pre>
<p>}</p>
<pre><code>
26、有 N件物品和一个容量为V的背包,每件物品有各自的价值且只能被选择一次,要求在有限的背包容量下,装入的物品总价值最大。(01背包)
</code></pre>
<pre><code>for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
// 当前背包容量装不进第i个物品,则价值等于前i-1个物品
if(j < v[i])
f[i][j] = f[i - 1][j];
// 能装,需进行决策是否选择第i个物品
else
f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
}
</code></pre>
<pre><code>
27、有 N种物品和一个容量是 V的背包,每种物品都有无限件可用,要求在有限的背包容量下,装入的物品总价值最大。(完全背包)
暴力:
for(int i = 1 ; i<=n ;i++)
for(int j = 0 ; j<=m ;j++)
{
for(int k = 0 ; k*v[i]<=j ; k++)
f[i][j] = max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
}
![](https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220409003938.png)
for(int i = 1 ; i <=n ;i++)
for(int j = 0 ; j <=m ;j++)
{
f[i][j] = f[i-1][j];
if(j-v[i]>=0)
f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);
}
28、有 N种物品和一个容量是 V的背包。
第 i种物品最多有 si件,每件体积是 vi
,价值是 wi。求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
</code></pre>
<p>1、死拆<br> while(n–)<br> {<br> cin>>v>>w>>s;<br> while(s–)<br> {<br> a[++t]=v;<br> b[t]=w;<br> }//把多重背包拆成01背包<br> }<br> for(int i=1;i<=t;i++)<br> for(int j=m;j>=a[i];j–)<br> dp[j]=max(dp[j-a[i]]+b[i],dp[j]);//直接套01背包的板子</p>
<pre><code>2、暴力,枚举这个物品拿0个,1个,2个...
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++)
for(int k=0;k<=s[i]&&k*v[i]<=j;k++)
f[i][j]=max(f[i][j],f[i-1][j-v[i]*k]+w[i]*k);
</code></pre>
<pre><code>![](https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220409005031.png)
然而,当数据较大时(一俩千),需要用二进制优化
优化如下,每种物品最多有si件,可以凑成1件、2件,4件,8件...
</code></pre>
<p> int cnt = 0; //分组的组别<br> for(int i = 1;i <= n;i ++)<br> {<br> int a,b,s;<br> cin >> a >> b >> s;<br> int k = 1; // 组别里面的个数<br> while(k<=s)<br> {<br> cnt ++ ; //组别先增加<br> v[cnt] = a * k ; //整体体积<br> w[cnt] = b * k; // 整体价值<br> s -= k; // s要减小<br> k <em>= 2; // 组别里的个数增加<br> }<br> //剩余的一组<br> if(s>0)<br> {<br> cnt ++ ;<br> v[cnt] = a</em>s;<br> w[cnt] = b*s;<br> }<br> }</p>
<pre><code>n = cnt ; //枚举次数正式由个数变成组别数
</code></pre>
<p>下面套01背包即可</p>
<pre><code>
29、有 N组物品和一个容量是 V的背包。每组物品有若干个,同一组内的物品最多只能选一个。求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。(分组背包)
</code></pre>
<pre><code>for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
f[i][j]=f[i-1][j];
for(int k=0;k<s[i];k++)
if(j>=v[i][k])f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
}
每组内挨个更新f[i][j]
</code></pre>
<pre><code>
30、从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。
找某个路径即可想到bfs,但是求最大值,就想到dp
对于数字三角型,可以考虑从底向上,可以避免边界问题
for(int i=n;i>=1;i--){
for(int j=i;j>=1;j--)
f[i][j]=max(f[i+1][j],f[i+1][j+1])+f[i][j];
}
31、给定一个长度为 N的数列,求数值严格单调递增的子序列的长度最长是多少。
又是求一个最值,考虑dp
![](https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220409005953.png)
</code></pre>
<pre><code>int mx = 1; // 找出所计算的f[i]之中的最大值,边算边找
for (int i = 0; i < n; i++) {
f[i] = 1; // 设f[i]默认为1,找不到前面数字小于自己的时候就为1
for (int j = 0; j < i; j++) {
if (w[i] > w[j]) f[i] = max(f[i], f[j] + 1); // 前一个小于自己的数结尾的最大上升子序列加上自己,即+1
}
mx = max(mx, f[i]);
}
</code></pre>
<p>栈优化后<br> t.push_back(w[0]);<br> for(int i=1;i<n;i++)<br> {<br> if(w[i]>t.back())t.push_back(w[i]);<br> else {<br> int index=lower_bound(t.begin(),t.end(),w[i])-t.begin();<br> t[index]=w[i];<br> }<br> }</p>
<pre><code>
32、给定两个长度分别为 N和 M的字符串 A和 B
,求既是 A的子序列又是 B的子序列的字符串长度最长是多少。(最长公共子序列)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])f[i][j]=f[i-1][j-1]+1;
else f[i][j]=max(f[i-1][j],f[i][j-1]);
}
33、给定两个字符串 A和 B,现在要将A经过若干操作变为B。将A变为B至少需要进行多少次操作。
</code></pre>
<pre><code>for(int i=0;i<=n;i++)f[i][0]=i;
for(int i=0;i<=m;i++)f[0][i]=i;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
f[i][j]=min(f[i-1][j],f[i][j-1])+1;
if(a[i]==b[j])f[i][j]=min(f[i][j],f[i-1][j-1]);
else f[i][j]=min(f[i][j],f[i-1][j-1]+1);
}
}
</code></pre>
<pre><code>
34、每堆石子有一定的质量,可以用一个整数来描述,现在要将这 N堆石子合并成为一堆。每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。
</code></pre>
<pre><code>for(int len =1;len<n;len++)
for(int i =1;i+len <= n;i++)
{
int j=i+len;
f[i][j]=0x3f3f3f3f;
for(int k=i;k<=j-1;k++)
{
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
}
}
</code></pre>
<pre><code>
35、他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
将子节点的编号存到son容器中
for(int i=1;i<=n-1;i++){
int l,k;
cin>>l>>k;
son[k].push_back(l);
v[l]=1;
}
寻找根节点(度为0)
for(int i=1;i<=n;i++){
if(v[i]==0)root=i;
}
遍历根节点
分俩种情况,在遍历子节点
void dfs(int x){
f[x][0]=0;
f[x][1]=h[x];
for(int i=0;i<son[x].size();i++){
int y=son[x][i];
dfs(y);
f[x][0]+=max(f[y][1],f[y][0]);
f[x][1]+=f[y][0];
}
}
36、记忆化搜索
</code></pre>
<p>重点是,当该点已经被搜过时,直接返回值<br> int dp(int x,int y){<br> int &v = f[x][y]; //Y总说的小技巧,等于把f[x][y]简化成了v,如果v发生变化,f[x][y]也会随之变化<br> if(v != -1) return v; //如果已经计算过了,就可以直接返回答案<br> v = 1; //注意v要先赋值为1哦~<br> for(int i = 0;i < 4;i ++){ //四个方向<br> int xx = x + dx[i];<br> int yy = y + dy[i];<br> if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && h[x][y] > h[xx][yy]){ //判断这点是否能走<br> v = max(v,dp(xx,yy) + 1); //更新<br> }<br> }<br> return v; //别忘了返回v啊(被坑了<br>}</p>
<pre><code>
37、区间选择
排序左端点或者右端点
请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。
输出选择的点的最小数量。
for(int i=0;i<n;i++){
ans++;
int right=a[i].first;
while(right>=a[i+1].second&&i+1<n)i++;
}
请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。
输出可选取区间的最大数量。
for(int i=0;i<n;i++){
int Maxr=a[i].second;
ans++;
while(Maxr>=a[i+1].first&&i+1<n)Maxr=min(Maxr,a[i+1].second),i++;
}
请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小
类似于有N个班要去教室上课,需要多少教室
a[idx].second=0;//左端点负值未0
a[idx+1].second=1;//右端点赋值为1
idx=idx+2;
遇到上课的班级教室加1
遇到下课的班级教室减1
求教室的峰值
for(int i=0;i<idx;i++){
if(a[i].second==0)ans++;
maxx=max(ans,maxx);
if(a[i].second==1)ans--;
}
37、区间合并
假定每个果子重量都为 1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使达达耗费的体力最少,并输出这个最小的体力耗费值。(哈夫曼树)
先用优先队列储存
priority_queue<int ,vector<int>,greater<int> > heap;
while(n--){
int x;
scanf("%d",&x);
heap.push(x);
}
每次将前俩取出来相加再推进去
while(heap.size()>1){
int a=heap.top();
heap.pop();
int b=heap.top();
heap.pop();
res+=a+b;
heap.push(a+b);
}
38、现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小
数组的中位数即可:nth_element(a,a+(n>>1),a+n);
39、从 1∼n这 n个整数中随机选取任意多个,输出所有可能的选择方案
枚举一个坑时,俩个坑时...
40、输出输入数字用数码 1∼9不重复不遗漏地组成带分数表示的全部种数。
</code></pre>
<p>将10个数分三段<br>没段取成a,b,c;<br> for(int i=0;i<9;i++)<br> num[i]=i+1;<br> do{<br> for(int i=0;i<=6;i++)<br> for(int j=((9-i)/2)+i-1;j<=7;j++)<br> {<br> int a=fun(0,i);<br> int b=fun(i+1,j);<br> int c=fun(j+1,8);<br> if(a<em>c+b==n</em>c){<br> cnt++;<br> }<br> }<br> }while (next_permutation(num, num+9));</p>
<pre><code>41、直接输出结果的很有可能是二分答案
二分一定要开long long
</code></pre>
<p>要么while(r-l>0),选择的时候就mid+1<br> while (l < r)<br> {<br> int mid = l + r >> 1;<br> if (success(mid))<br> {<br> r = mid;<br> }<br> else<br> {<br> l = mid + 1;<br> }<br> } </p>
<pre><code>或者while(r-l>1)
选择的时候直接mid
while (l + 1 < r) {
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid;
}
</code></pre>
<p>```</p>
<p>42、在 1∼N的某个排列中有多少个连号区间<br>比如2 5 6 3 4<br>第二位到第五位的最大值为6,最小值为3,6-3是不是中间隔的数字</p>
<p>43、小明对数位中含有 2、0、1、9的数字很感兴趣(不包括前导 0<br>),在 1到 40中这样的数包括 1、2、9、10至 32、39和 40,共 28个,他们的和是 574。请问,在 1到 n中,所有这样的数的和是多少?</p>
<p>打表yyds</p>
<p>44、涉及到日期,考虑闰年的2月(能同时被4和100整除,或者能被400整除)<br>if(month==2)<br>{bool leap = year % 4 == 0 && year % 100|| year % 400==0;//判断是不是闰年,看到日期类的题一定要注意2月这个毒瘤</p>
]]></content>
</entry>
<entry>
<title>SQL语言</title>
<url>/2022/03/19/SQL%E8%AF%AD%E8%A8%80/</url>
<content><![CDATA[<h1 id="SQL语言"><a href="#SQL语言" class="headerlink" title="SQL语言"></a>SQL语言</h1><h2 id="1、模式定义"><a href="#1、模式定义" class="headerlink" title="1、模式定义"></a>1、模式定义</h2><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193540.png"><br>例题:</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193549.png"><br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193609.png"></p>
<h2 id="2、模式删除"><a href="#2、模式删除" class="headerlink" title="2、模式删除"></a>2、模式删除</h2><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193620.png"><br>注:<img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193627.png"></p>
<h2 id="3、表的定义与删除"><a href="#3、表的定义与删除" class="headerlink" title="3、表的定义与删除"></a>3、表的定义与删除</h2><h3 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404212606.png"></p>
<h3 id="删除"><a href="#删除" class="headerlink" title="删除"></a>删除</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193650.png"><br>例题:<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193701.png"><br>注:<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193713.png"></p>
<h3 id="修改"><a href="#修改" class="headerlink" title="修改"></a>修改</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193723.png"><br>例题:<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193732.png"><br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193738.png"></p>
<h2 id="4、索引的建立与删除"><a href="#4、索引的建立与删除" class="headerlink" title="4、索引的建立与删除"></a>4、索引的建立与删除</h2><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193754.png"></p>
<h3 id="建立"><a href="#建立" class="headerlink" title="建立"></a>建立</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193801.png"><br>注:<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193820.png"><br>例题:<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193831.png"></p>
<h3 id="修改-1"><a href="#修改-1" class="headerlink" title="修改"></a>修改</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193836.png"></p>
<h3 id="删除-1"><a href="#删除-1" class="headerlink" title="删除"></a>删除</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193842.png"></p>
<h2 id="5、查询"><a href="#5、查询" class="headerlink" title="5、查询"></a>5、查询</h2><h3 id="查询所有列-amp-查询部分列"><a href="#查询所有列-amp-查询部分列" class="headerlink" title="查询所有列&查询部分列"></a>查询所有列&查询部分列</h3><p>例题:</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193944.png"></p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404193953.png"></p>
<h3 id="结果去重"><a href="#结果去重" class="headerlink" title="结果去重"></a>结果去重</h3><pre><code>加上distinct关键词就好了
放在需要去重打字段的前面
</code></pre>
<h3 id="聚集函数"><a href="#聚集函数" class="headerlink" title="聚集函数"></a>聚集函数</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404212549.png"></p>
<pre><code>只要不是空都会算一个,相同的也会算一个
</code></pre>
<h3 id="分组查询(group-by,如果要进行筛选,就用having-x3D-where-条件)"><a href="#分组查询(group-by,如果要进行筛选,就用having-x3D-where-条件)" class="headerlink" title="分组查询(group by,如果要进行筛选,就用having=where-条件)"></a>分组查询(group by,如果要进行筛选,就用having=where-条件)</h3><h3 id="连接"><a href="#连接" class="headerlink" title="连接"></a>连接</h3><h4 id="等值连接(自身连接)"><a href="#等值连接(自身连接)" class="headerlink" title="等值连接(自身连接)"></a>等值连接(自身连接)</h4><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194013.png"> </p>
<pre><code>两个表的笛卡尔积附加一个等值的条件,就用这个条件合在了一起
</code></pre>
<h3 id="外连接"><a href="#外连接" class="headerlink" title="外连接"></a>外连接</h3><h4 id="左连接"><a href="#左连接" class="headerlink" title="左连接"></a>左连接</h4><pre><code>left outer join
就是把左边这个表和右边那个表根据一个条件连接起来,最后再加上左表剩余的部分
注:剩余的值虽然保留在结果中,但是会加null
</code></pre>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194020.png"></p>
<h3 id="嵌套查询"><a href="#嵌套查询" class="headerlink" title="嵌套查询"></a>嵌套查询</h3><pre><code>select 字段(*) from 哪个表 where 该条件存在于 in (一个查询)范围内的数据
</code></pre>
<h4 id="带有any-all的子查询"><a href="#带有any-all的子查询" class="headerlink" title="带有any all的子查询"></a>带有any all的子查询</h4><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194027.png"></p>
<pre><code>找出大于后面范围的所有数据
</code></pre>
<h4 id="exists"><a href="#exists" class="headerlink" title="exists"></a>exists</h4><p>例题:</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194035.png"></p>
<h3 id="集合查询"><a href="#集合查询" class="headerlink" title="集合查询"></a>集合查询</h3><p>并(union)</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194125.png"></p>
<p>交(intersect)<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194134.png"></p>
<p>差(except)<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194143.png"></p>
<h2 id="6、数据的插入、修改、删除"><a href="#6、数据的插入、修改、删除" class="headerlink" title="6、数据的插入、修改、删除"></a>6、数据的插入、修改、删除</h2><h4 id="插入"><a href="#插入" class="headerlink" title="插入"></a>插入</h4><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194150.png"></p>
<h4 id="修改-2"><a href="#修改-2" class="headerlink" title="修改"></a>修改</h4><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194203.png"></p>
<h4 id="删除-2"><a href="#删除-2" class="headerlink" title="删除"></a>删除</h4><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194214.png"></p>
<h2 id="7、视图"><a href="#7、视图" class="headerlink" title="7、视图"></a>7、视图</h2><h3 id="创建视图"><a href="#创建视图" class="headerlink" title="创建视图"></a>创建视图</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194221.png"></p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194225.png"><br>例题:<br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194232.png"></p>
<h3 id="删除视图"><a href="#删除视图" class="headerlink" title="删除视图"></a>删除视图</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194249.png"></p>
<h3 id="查询视图"><a href="#查询视图" class="headerlink" title="查询视图"></a>查询视图</h3><p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220404194259.png"></p>
]]></content>
</entry>
<entry>
<title>二分查找与二分答案</title>
<url>/2022/04/06/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/</url>
<content><![CDATA[<h2 id="二分查找与二分答案"><a href="#二分查找与二分答案" class="headerlink" title="二分查找与二分答案"></a>二分查找与二分答案</h2><pre><code>二分查找:
int k=lower_bound(a,a+n, l)-a;
第一个大于或者等于
如果不存在则判断a【k】是否等于该值
二分答案:
while (r - l > 1e-8) {
// 步骤 A: 找中间值
double mid = (l + r) / 2;
// 步骤 B: 判断
if (mid * mid * mid < x) l = mid;
else r = mid;
}
</code></pre>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220406191657.png"></p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220406191710.png"></p>
<pre><code>#include<iostream>
using namespace std;
const int N=100005;
int n,q,x,a[N];
int main(){
scanf("%d%d",&n,&q);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
while(q--){
scanf("%d",&x);
int l=0,r=n-1;
while(l<r){//找到第一个x
int mid =(l+r)>>1;
if(a[mid]<x)l=mid+1;
else r=mid;
}
if(a[l]!=x){
printf("-1 -1\n");
continue;
}
int l1=l,r1=n;
while(l1+1<r1){//找最后一个x
int mid = (l1+r1)>>1;
if(a[mid]<=x)l1=mid;
else r1=mid;
}
cout<<l<<" "<<l1<<endl;
}
return 0;
}
</code></pre>
<p>&& </p>
<pre><code>#include <bits/stdc++.h>
using namespace std;
int main(){
int i,j,n,m,a[100001],l;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i];
for(int j=0;j<m;j++)
{
cin>>l;
int k=lower_bound(a,a+n, l)-a;
if(k==n||a[k]!=l){cout<<-1<<" "<<-1<<endl;}
else
{
int h=upper_bound(a,a+n,l)-a-1;
cout<<k<<" "<<h<<endl;
}
}
return 0;
}
</code></pre>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220406191830.png"><br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220406191921.png"><br><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220406192003.png"></p>
<p>lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。</p>
<p>lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个 大于或等于 num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。</p>
<p>upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。</p>
<p>在从大到小的排序数组中,重载lower_bound()和upper_bound()</p>
<p>lower_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。</p>
<p>upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。‘</p>
<p><img src="https://tuccc.obs.cn-north-4.myhuaweicloud.com/img/20220406194230.png"></p>
<pre><code>#include <iostream>
#include <cstdio>
using namespace std;
double x;
int main() {
cin >> x;
// 确定边界值
double l = -100000, r = 100000;
// 注意循环条件处理精度问题
while (r - l > 1e-8) {
// 步骤 A: 找中间值
double mid = (l + r) / 2;
// 步骤 B: 判断