0%

参考视频: 驾考宝典科目一肖肖2小时抢分课(2023年7月)新规版

笔记基于网友评论,并根据我的理解进行了修改。

笔记会有少数例外,需要通过刷题来发现。

扣分

1、扣分分值为1 3 6 9 12,取消2分了!
2、1分:会车,普倒掉,使用灯光(故障停车不打双闪3分,信号灯6分),年检,安全带,禁令标志线
3、3分:普逆,手持电话,前方排队穿插占道,高低速,高不按道,故障停车不用灯和标志,三不让(让行 让人 让校车)
4、6分:占应急车道,不按信号灯,暂扣期间驾驶,逃逸轻微财产(不构成犯罪),危险爆炸未挂警示标或限行区
5、9分:准驾车型不符,无校车资格,高城快违停
6、12分:饮酒,高倒掉逆,替人接受处罚,逃逸轻伤以上(不构成犯罪)

号牌扣分
1、不按规定安装扣3分
2、未挂或故意遮挡扣9分
3、伪造变造12分

超速扣分
3 6 6 12
1 6 9 6 12

超员
1、7下3 6,7上6 9,20起50%为界定
2、超100%,扣12
3、校公旅,20以下6分,20以上12

超载
1 3 6,以30% 50%界定

罚款

1、200以下:转让,车身颜色,安检
2、20-200:补领用原证,实习期单独上高速,信息变更(不合规使用),让撤不撤造成堵塞罚200
3、200-500:逾期不审验,隐瞒欺骗补领,身体不适合仍驾驶(不应该有证),公路客运超员未达20%
4、200-2000:拼装、报废,超速50%(处吊销驾驶证),把车给无证人开,非法安装报警器
5、500、2000:虚假材料500一年不申领,考试贿赂2000三年不申领。假1撤3

审验
1、弄虚作假1000以下
2、代替他人2000以下
3、组织他人3倍以下,最高2万
(假审1,代审2,组3倍2)
代记分3倍5,组5倍10

酒驾
1、饮酒20-80:暂扣6个月,扣12分,罚1000-2000
2、再次饮酒:吊销,拘留10日以下,罚1000-2000
3、醉酒80:吊销5年
(酒驾罚款1至2,醉驾吊销禁5年,重大事故构成犯罪,终身)

驾驶证

1、年龄限制分3档:18 20 22,有上限都是60岁。客牵不得初次申。轻牵挂20,重牵挂22。

2、吊销情形
假1,吊2,撤3,醉(+超员速)5,逃终身

3、补证换证
车相关,找登记地
人相关,找核发地(或以外)

4、驾驶证审验
记分周期结束30日内
有效期满换证
延期审不超过3年

5、实习期
不得单独上高速,3年以上老司机陪同,不能参加学法减分

6、时间相关
6年,10年,长期
信息变更30日,有效期满90日

7、申请增加准驾车型
周期轻1中2大3

8、机动车注册变更登记
只有加装防撞不变更

9、上路必带两证两标一号牌,扣车
扣行驶证都是错

10、满分教育
满12,法规(7天)
满24,法规,道路(14天)
满36,法规,场地,道路(最多60天)

11、学法减分
公益11,现场12,网上31
周期12个月,未满12分可申,最高减6分
3周期内有部分处罚,不可申请

12、责任判定
危险驾驶罪,追逐竞驶、醉驾(未造成后果,拘役罚金)
交通肇事罪,酒驾毒驾、无牌报废、肇事逃逸(选除3个“未”以外的)

13、赔偿责任
车对车,伪造现场(全责),货车货物没捆好(货车全责)
车对人,车无错(不超过10%),人故意车静止(不赔)

14、判刑判几年
未逃逸,3年以下
死亡后逃逸,3-7年
逃逸致死亡,7年以上

通行原则

右让左,弯让直,右方先行
禁止停车:口五站三
加速、迅速、随意、空挡滑行都是错的
减速、缓慢、避让都是对的
一停二看三通过
会车减速靠右,遇人停车减速

车速车距

无线城3公4,有线城5公7
特殊速度30
高速车道最低,100 60,110 90 60
高速车距,>100 100,<100 50
低能见度车速车距,261,145,520

仪表盘

只有P制动是工作,其他都是故障

交警手势

左转弯待转:单左手下压
减速慢行:单右手下压
变道:单右手向中间摆
靠边停车:左掌上 右手下方左右摆

其他

停车线蓝色免费,白色收费,黄色专属

文章为本人原创,同步在洛谷发布。

您是否为经常使用不同的电脑,但编程环境无法简单迁移而苦恼呢?
别急,看看这篇文章 : )
把系统装到U盘里,随身携带。

其实就是为了解决学校没有个人专用电脑,也不允许自带电脑的问题。

因为有些老机器只支持 BIOS+MBR,有些新机器只支持 UEFI+GPT,所以需要同时支持 BIOS 和 UEFI。此方法可能不适用于硬件资源虚拟化或者锁USB端口的机器。

本文部分内容需要一定的知识储备,不适合纯小白。
乱搞可能会造成数据丢失,请严格按照本教程操作。


使用体验

  1. 开机即可写代码,免去调配置的繁琐。
  2. 代码写了一半要离开,按下 Ctrl+s 保存代码,然后关机。再也不用复制到U盘或者发邮箱。
  3. 可以把系统调成最舒服的样子。

一、准备工作

  1. Vmware Workstation(如何安装请自行百度)
  2. 64位 Ubuntu ISO 文件(UEFI 不支持 32 位系统)
  3. 高性能U盘,至少 USB 3.0 32G,推荐 64G 及以上。如果用固态硬盘就更好了。U盘速度直接影响使用体验,请务必使用能够长时间保持写入速度的U盘。(用了两年,每次 apt upgrade 都怀疑人生,问自己为什么不买一个更好的U盘)

二、新建虚拟机并编辑配置

新建虚拟机 -> 典型 -> 稍后安装操作系统 -> Linux(Ubuntu 64位) -> 最大磁盘大小0.001GB -> 按照需要调整虚拟机硬件配置

  1. CD/DVD
    选择 Ubuntu ISO 文件位置,启动时连接

  2. USB控制器
    USB兼容性:USB 3.0

  3. 添加硬盘
    计算机管理 -> 磁盘管理
    记住自己的U盘的磁盘编号(比如我这里是磁盘3)
    虚拟机设置 -> 添加 -> 硬盘 -> SCSI -> 使用物理磁盘 -> 选择自己的U盘,并使用整个磁盘

  4. 设置 UEFI 启动
    虚拟机设置 -> 选项 -> 高级 -> 固件类型 -> UEFI
    还是没有找到的看这里

三、U盘分区

这会删除U盘里所有的数据。
开启虚拟机。如果提示“物理磁盘已被使用”,请关闭所有可能使用这个U盘的程序,拔出U盘后重新插入。
成功设置 UEFI 后,开机应该看到这个画面。如果没有看到,请检查之前的步骤。
选择"Try Ubuntu without installing"。开机后启动 Gparted。

此时U盘应该是 sdb。如果不是,请把下面所有的 sdb 换成您自己的 sdX。

在 sdb 建立 GPT 分区表。

第一个分区设置 fat32,用来拷贝文件。(因为win7似乎只能识别第一个分区)
ESP分区(下图第三个)至少 100MB,设置 boot 和 esp 标识。
在分区上右键可以修改标识(Manage Flags)。
如果您真的不会使用 Gparted,看这里

下图仅供参考。如果不需要在 Windows 下拷贝文件,可以不设置第一个 fat32 分区。

注意
1. 虚拟机关闭后,win10 会提醒格式化所有无法识别的分区,千万不要手抖点确定。 2. 分区设置请慎重考虑,之后更改会很麻烦。系统分区尽量划分得大一些。如果内存充足,可以不设置 swap。

您是不是被最后的 1MB 折磨,强迫症发作了?滑稽
现在我们来解决这个问题,向这个空间添加 bios_grub 标记。

这里简单提及一下这个标记的作用。GPT 兼容 MBR,如果要让 grub 在 GPT 上使用 MBR 模式安装的话,需要设置这个标记。这个分区有以下三个特点:1MB 容量,不需要格式化,设置 bios_grub 标记。(https://my.oschina.net/abcfy2/blog/491140)

在虚拟机中打开终端

1
2
3
4
5
6
7
8
9
sudo gdisk /dev/sdb
n
# 默认编号,回车就行
# 默认开始位置,回车
# 默认结束位置,回车
EF02 # EF02 就是 bios_grub
p # 看到 Name 有 BIOS boot partition 就可以了
w
y
最终是这样的。

四、开始 UEFI 安装

双击桌面上的"Install Ubuntu"。
如果您没有安装 Ubuntu 的经历,点击这里了解流程。
安装过程中下载更新很慢,建议断网。其他设置默认,直到这一步。
把 ext4 挂载到 /。也可以按照自己的需要来设置。
启动引导器一定要装在 /dev/sdb 上,不能装在别的硬盘(比如 sda),也不能装在单个分区上。
之后设置用户名和密码。尝试在等待安装的时间里切一道题。
安装好后,试一下能不能 UEFI 启动。

再次提醒
关闭虚拟机后,如果您的电脑突然多了一堆盘符,提醒格式化,千万不要点击确定。可以使用 DiskGenius,在不明分区上右键,删除驱动器号(盘符)。那么在这台电脑上,就不会再显示这些分区了。

五、添加 BIOS 启动

模仿切换 UEFI 的步骤,切换回 BIOS。
虚拟机设置 -> 选项 -> 高级 -> 固件类型 -> BIOS

重新连接 CD/DVD,启动虚拟机。

刚启动应该看见紫黑色背景,下方有一个小人和键盘图标。没有任何选项,自动进入这个画面。如果没有看到,请检查是否已经切换回 BIOS。
选择 Try Ubuntu。

现在假设您的系统安装在 sdbX(本文为 sdb2)。

1
2
sudo mount /dev/sdbX /mnt
sudo grub-install --target=i386-pc --recheck --boot-directory=/mnt/boot /dev/sdb

如果报错:

1
2
3
4
Installing for i386-pc platform.
grub-install: warning: this GPT partition label contains no BIOS Boot Partition; embedding won't be possible.
grub-install: warning: 无法嵌入。在此次安装中 GRUB 只能通过使用块列表安装。但是块列表是不可信赖的,不推荐使用。.
grub-install:错误: will not proceed with blocklists.
请检查是否正确标记了 bios_grub。

重启一下,看看能不能 BIOS 启动,然后尝试 UEFI 启动。
如果没有问题,那么,完结撒花!


后记

  1. 如果您不知道如何设置电脑从U盘启动。https://zhidao.baidu.com/question/416256793.html
  2. 如果您的学校采用全虚拟机教学,那么是没有办法使用自己的系统的(为什么我的锐捷云课堂不行,别人可以?),为您默哀三秒钟。

参考文章:
https://my.oschina.net/abcfy2/blog/491140
https://help.ubuntu.com/community/Installation/UEFI-and-BIOS/original-attempt#Make_a_system_bootable_in_UEFI_as_well_as_BIOS
https://help.ubuntu.com/community/UEFI

南京大学一流学科专题营
计算机科学&人工智能
NJUSC 2019游记
本文谢绝任何形式的转载

写在前面

说是说游记,其实就是记录一下题目。
题面可能会有错误,所有配图都是自己画的。
学业繁忙,告辞。

数学争先活动

物理争先活动

创新编程活动一

T1

出原题,有一位同学五分钟切了
[AGC018C] Coins

T2

题意:
\(n\) 个点 \(m\) 条边的无向图上有 \(k\) 个必经点,起点终点任意,求走 \(d\) 步的方案数。

题解:
\(k\) 很小,容斥+矩阵快速幂

T3

已知平面范围 \(x,y \in [-1000,1000]\),给定你到平面上 \(100\) 个确定点的距离,其中 \(40\) 个不准确,剩余 \(60\) 个有 \(\pm 1\) 的误差,请求出你的坐标。\(20\) 次询问。

创新编程活动二

T1

又是原题,连样例也不改,让人angry
[AGC013C] Ants on a Circle

T2

题意:
序列 \(x_1,x_2,\cdots,x_n\),每个元素等于 \(0\)\(1\)
现在取出 \(n-3\) 个元素构成一个方程,\(x_{i_1}+x_{i_2}+ \cdots +x_{i_{n-3}}=2\),其中 \(1 \leq i_1 < i_2 < \cdots < i_{n-3} \leq n\)
从这些方程里挑出 \(4\) 个组成方程组。方程组中方程顺序不同但是方程相同,认为是同一个方程组。
求有解的方程组数量。

题解:
据说 \(n\le13\) 打表,\(n \ge14\) 有组合数规律

T3

题意:
求大小在十进制数 \(a,b\) 之间的所有三进制数,数位上 \(1\) 的出现的次数之和。 \(1 \leq a,b \leq 10^{350000}\)

题解(skyline tql):
分治fft进制转换,然后状压dp。100分要压位,90分不用。维护前后两半部分的三进制还有 10 的幂的三进制,然后就只用算乘法了。

边权是一次函数,求m个时刻树上最远点对之间的距离。
考虑点分,每个点到根的距离都是一个一次函数,维护下凸包。
在合并凸包的时候可以维护全局答案凸包。应该使用启发式合并,但是由于常数原因放弃了。

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
#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <set>
#include <vector>
#include <climits>
#define Pair pair<LL,LL>
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
using namespace std;
typedef long long LL;
const int MAXN=1e5+5;
const int MAXM=1e6+5;
struct Line {
mutable LL k,b,p;//y=kx+b
Line() {}
Line(LL k,LL b,LL p):k(k),b(b),p(p){}
bool operator<(const Line &res) const {return k<res.k;}
} anss[MAXN];
typedef multiset<Line>::iterator mlit;
typedef vector<Pair>::iterator vcit;
struct Data:multiset<Line> {
inline LL fl(LL a,LL b) {
if ((a^b)<0) return a/b-(a%b!=0);
return a/b;
}
inline bool check(iterator x,iterator y) {//pop y?
if (y==end()) {x->p=INT_MAX;return false;}
if (x->k == y->k) x->p=((x->b > y->b)?INT_MAX:INT_MIN);
else x->p=fl(y->b - x->b, x->k - y->k);
return x->p >= y->p;
}
inline void add(LL k,LL b) {
mlit t=insert(Line(k,b,0)),y=t,x=t;
y++;
while (check(t,y)) erase(y++);
if (t!=begin() && check(--x,t)) erase(t++),check(x,t);
t=x;
while (t!=begin() && (--x)->p >= t->p) erase(t++),check(x,t),t=x;
}
} ans;
int head[MAXN],vet[MAXN*2],nxt[MAXN*2],num;
Pair w[MAXN*2];
int sz[MAXN],mxs[MAXN],rt;
bool vis[MAXN];
int n,m;
inline int read() {
char ch=getchar();int sum=0;
while (ch>'9' || ch<'0') ch=getchar();
while (ch>='0' && ch<='9') sum=sum*10+ch-'0',ch=getchar();
return sum;
}
void print(LL x) {
if (x>9) print(x/10);
putchar(x%10+'0');
}
inline void addedge(int x,int y,int k,int b) {
num++;vet[num]=y;w[num]=mp(k,b);nxt[num]=head[x];head[x]=num;
num++;vet[num]=x;w[num]=mp(k,b);nxt[num]=head[y];head[y]=num;
}
void getroot(int x,int fa,int tot) {
sz[x]=1;mxs[x]=0;
for (int e=head[x];e;e=nxt[e]) {
int v=vet[e];
if (v==fa || vis[v]) continue;
getroot(v,x,tot);
sz[x]+=sz[v];
mxs[x]=max(mxs[x],sz[v]);
}
mxs[x]=max(mxs[x],tot-sz[x]);
if (mxs[x]<mxs[rt]) rt=x;
}
void getpath(int x,int fa,LL k,LL b,Data &a) {
int son=0;
for (int e=head[x];e;e=nxt[e]) {
int v=vet[e];
if (v==fa || vis[v]) continue;
getpath(v,x,k+w[e].fi,b+w[e].se,a);
son++;
}
if (!son) a.add(k,b);
}
inline void update(Data &a,Data &b) {
vector<Pair> vec1,vec2;
for (mlit it=a.begin();it!=a.end();++it) {
if (!vec1.empty() && (it->k)==vec1[vec1.size()-1].fi) {
vec1[vec1.size()-1].se=max(vec1[vec1.size()-1].se,it->b);
}
else vec1.push_back(mp(it->k,it->b));
}
for (mlit it=b.begin();it!=b.end();++it) {
if (!vec2.empty() && (it->k)==vec2[vec2.size()-1].fi) {
vec2[vec2.size()-1].se=max(vec2[vec2.size()-1].se,it->b);
}
else vec2.push_back(mp(it->k,it->b));
}
LL s1=0,s2=0;
while (s1<vec1.size() && s2<vec2.size()) {
ans.add(vec1[s1].fi+vec2[s2].fi,vec1[s1].se+vec2[s2].se);
if (s1+1==vec1.size()) s2++;
else if (s2+1==vec2.size()) s1++;
else {
double x1=-(vec1[s1+1].se-vec1[s1].se)/(double)(vec1[s1+1].fi-vec1[s1].fi);
double x2=-(vec2[s2+1].se-vec2[s2].se)/(double)(vec2[s2+1].fi-vec2[s2].fi);
if (x1<x2) s1++;
else s2++;
}
}
}
Data merge(int l,int r,vector<Data> &q) {
if (l==r) {
Data tt;
tt.add(0,0);
update(tt,q[0]);
return q[l];
}
int mid=(l+r)>>1;
Data t1=merge(l,mid,q),t2=merge(mid+1,r,q);
if (t1.size()>t2.size()) swap(t1,t2);
update(t1,t2);
for (mlit it=t1.begin();it!=t1.end();++it) t2.add(it->k,it->b);
return t2;
}
void solve(int x,int tot) {
vis[x]=1;
vector<Data> vec;
Data blank;blank.add(0,0);
for (int e=head[x];e;e=nxt[e]) {
int v=vet[e];
if (vis[v]) continue;
vec.push_back(blank);
getpath(v,x,w[e].fi,w[e].se,vec[vec.size()-1]);
}
if (!vec.empty()) merge(0,vec.size()-1,vec);
for (int e=head[x];e;e=nxt[e]) {
int v=vet[e];
if (vis[v]) continue;
rt=0;
int tt=sz[v];
if (tt>sz[x]) tt=tot-sz[x];
getroot(v,x,tt);
solve(rt,tt);
}
}
int main() {
n=read(),m=read();
ans.add(0,0);
for (int i=1;i<n;i++) {
int x=read(),y=read(),k=read(),b=read();
addedge(x,y,k,b);
}
mxs[0]=(n<<1);rt=0;
getroot(1,0,n);
solve(rt,n);
int top=0;
for (mlit it=ans.begin();it!=ans.end();++it) anss[++top]=(*it);
for (LL i=0,j=1;i<m;i++) {
while (anss[j].p<i) j++;
print(anss[j].k*i+anss[j].b);putchar(' ');
}
return 0;
}

http://codeforces.com/problemset/problem/1093/E
设元素 \(i\)\(A\) 中出现的位置是 \(pa[i]\) ,在 \(B\) 中出现的位置是 \(pb[i]\)
元素 \(i\) 如果有贡献,当且仅当 \(la \le pa[i] \le ra, lb \le pb[i] \le rb\),转换为二维数点问题。
树套树当然可以,cdq更快。
时间维已经有序, \(pa\)\(x\) 坐标用cdq解决, \(pb\)\(y\) 坐标用树状数组解决。

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
#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN=2e5+5;
const int MAXM=2e5+5;
struct node {
int op,x,y1,y2,val,ID;
} qu[MAXN+MAXM*4],qu1[MAXN+MAXM*4];
int a[MAXN],b[MAXN],pa[MAXN],pb[MAXN];
int c[MAXN];
int ans[MAXM];
int n,m,nn,nnn;
inline int read() {
int sum=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') sum=sum*10+ch-'0',ch=getchar();
return sum;
}
inline void update(int x,int val) {
for (;x<=n;x+=x&-x) c[x]+=val;
}
inline int query(int x) {
int sum=0;
for (;x;x-=x&-x) sum+=c[x];
return sum;
}
inline void clear(int x) {
for (;x<=n;x+=x&-x) {
if (!c[x]) break;
c[x]=0;
}
}
void cdq(int l,int r) {
if (l==r) return;
int mid=(l+r)>>1;
cdq(l,mid);cdq(mid+1,r);
int s1=l,s2=mid+1,s3=l-1;
while (s1<=mid && s2<=r) {
if (qu[s1].x<=qu[s2].x) {
if (qu[s1].op==2) update(qu[s1].y1,qu[s1].val);
qu1[++s3]=qu[s1];s1++;
}
else {
if (qu[s2].op==1) ans[qu[s2].ID]+=qu[s2].val*(query(qu[s2].y2)-query(qu[s2].y1-1));
qu1[++s3]=qu[s2];s2++;
}
}
while (s1<=mid) qu1[++s3]=qu[s1],s1++;
while (s2<=r) {
if (qu[s2].op==1) ans[qu[s2].ID]+=qu[s2].val*(query(qu[s2].y2)-query(qu[s2].y1-1));
qu1[++s3]=qu[s2];s2++;
}
for (int i=l;i<=r;i++) {
if (qu1[i].op==2) clear(qu1[i].y1);
qu[i]=qu1[i];
}
}
int main() {
n=read(),m=read();
for (int i=1;i<=n;i++) a[i]=read(),pa[a[i]]=i;
for (int i=1;i<=n;i++) b[i]=read(),pb[b[i]]=i;
for (int i=1;i<=n;i++) qu[++nn]=(node){2,i,pb[a[i]],pb[a[i]],1,0};
for (int i=1;i<=m;i++) {
int op=read();
if (op==1) {
nnn++;
int la=read(),ra=read(),lb=read(),rb=read();
qu[++nn]=(node){1,la-1,lb,rb,-1,nnn};
qu[++nn]=(node){1,ra,lb,rb,1,nnn};
}
else {
int x=read(),y=read();
qu[++nn]=(node){2,pa[b[x]],x,x,-1,0};
qu[++nn]=(node){2,pa[b[x]],y,y,1,0};
qu[++nn]=(node){2,pa[b[y]],y,y,-1,0};
qu[++nn]=(node){2,pa[b[y]],x,x,1,0};
swap(b[x],b[y]);
}
}
cdq(1,nn);
for (int i=1;i<=nnn;i++) printf("%d\n",ans[i]);
return 0;
}

gedit的配置

gedit首选项

查看

显示行号
启用自动换行,避免在单词内换行
突出显示当前行,匹配的括号

编辑器

制表符宽度4,不使用空格代替,启用自动缩进
保存前备份,间隔10分钟

字体和颜色

Ubuntu Mono 13
Oblivion

插件

启用外部工具

外部工具

添加Compile

快捷键F4
保存当前文档
输入无,输出在下方面板
使用范围所有文档,C++

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
fullname=$GEDIT_CURRENT_DOCUMENT_NAME
name=`echo $fullname | cut -d. -f1`
suffix=`echo $fullname | cut -d. -f2`
dir=$GEDIT_CURRENT_DOCUMENT_DIR
if [ $suffix="cpp" ]; then
if [ -f "./$name" ]; then
rm "./$name"
fi
g++ $fullname -o $name -O2 -Wall -lm
fi

添加Run

快捷键F5
保存无,输入无,输出在下方面板
使用范围所有文档,C++

1
2
3
4
5
6
7
8
#!/bin/sh
fullname=$GEDIT_CURRENT_DOCUMENT_NAME
name=`echo $fullname | cut -d. -f1`
suffix=`echo $fullname | cut -d. -f2`
dir=$GEDIT_CURRENT_DOCUMENT_DIR
if [ -f "$dir/$name" ]; then
gnome-terminal --hide-menubar --working-directory=$dir -- bash -c "ulimit -s unlimited; /usr/bin/time -f '\n%es %Us' \"$dir/$name\"; echo 'Press any key to return...'; read"
fi
报错解决:
(gnome-terminal:4874): GLib-GIO-CRITICAL **: g_setting_get: the format string may not contain '&' (key 'monospace-font-name' from schema 'org.gnome.desktop.interface'). This call will probably stop working with a future version of glib.
1
sudo gsettings set org.gnome.desktop.interface monospace-font-name 'Ubuntu Mono 13'

Sublime Text 3

虽然NOI Linux没有,但是THUWC有。

新建编译系统

找到 /opt/sublime_text/Packages/C++.sublime-package 里面的 C++ Single File.sublime-build,复制出来,新建编译系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"shell_cmd": "g++ \"${file}\" -o \"${file_path}/${file_base_name}\" -O2 -Wall -lm -std=c++11 && gnome-terminal --hide-menubar -- bash -c \"ulimit -s unlimited; /usr/bin/time -f '\n%es %Us' \"${file_path}/${file_base_name}\"; echo 'Press any key to return...'; read\" ",
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"selector": "source.c, source.c++",

"variants":
[
{
"name": "Compile Only",
"shell_cmd": "g++ \"${file}\" -o \"${file_path}/${file_base_name}\" -O2 -Wall -lm -std=c++11"
},
{
"name": "Run Only",
"shell_cmd": "gnome-terminal --hide-menubar -- bash -c \"ulimit -s unlimited; /usr/bin/time -f '\n%es %Us' \"${file_path}/${file_base_name}\"; echo 'Press any key to return...'; read\" "
}
]
}

顺便附带一个 Windows 版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"shell_cmd": "g++ \"${file}\" -o \"${file_path}/${file_base_name}\" -O2 -Wall -std=c++11 -Wl,--stack=1024000000 & start cmd /c \"\"${file_path}/${file_base_name}\" & pause \" ",
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"selector": "source.c, source.c++",

"variants":
[
{
"name": "Compile Only",
"shell_cmd": "g++ \"${file}\" -o \"${file_path}/${file_base_name}\" -O2 -Wall -std=c++11 -Wl,--stack=1024000000"
},
{
"name": "Run Only",
"shell_cmd": "start cmd /c \"\"${file_path}/${file_base_name}\" & pause \" "
}
]
}

保存为 C++_Competition.sublime-build

对拍及数据生成器

对拍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<bits/stdc++.h>
using namespace std;
int main() {
while (1) {
system("bash -c './datamaker $RANDOM > testdata.in'");
system("./baoli < testdata.in > testdata.ans");
clock_t start=clock();
system("./mysolution < testdata.in > testdata.out");
clock_t stop=clock();
if (system("diff testdata.out testdata.ans")) {
printf("GG\n");
break;
}
printf("AC in %lfs\n",(double)(stop-start)/CLOCKS_PER_SEC);
}
return 0;
}

数据生成器

1
2
3
4
5
6
7
8
9
#include<bits/stdc++.h>
using namespace std;
int main(int argc,char *argv[]) {
if (argc>1) srand(time(NULL)%10000*atoi(argv[1]));
else srand(time(NULL));

........
return 0;
}

从多项式乘法到快速傅里叶变换,Miskcoo
FFT用到的各种素数,Miskcoo

直接上三模数NTT

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
#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int MAXN=2100000;//两倍空间
int n,m,GP,r[MAXN],nn,mm;
LL a[MAXN],b[MAXN],c[MAXN],d[MAXN],ans[MAXN][4];
inline int read() {
char ch=getchar();int sum=0;
while (ch>'9' || ch<'0') ch=getchar();
while (ch>='0' && ch<='9') sum=sum*10+ch-'0',ch=getchar();
return sum;
}
void print(LL x) {
if (x>9) print(x/10);
putchar(x%10+'0');
}
//2009国家集训队论文:骆可强:《论程序底层优化的一些方法与技巧》
inline LL fast_mul(LL a,LL b,LL P) {
a%=P;b%=P;
LL d=(LL)floor(a*(long double)b/P+0.5);
LL res=a*b-d*P;
if (res<0) res+=P;
return res;
//return ((a*b-(LL)((LL)((long double)a/P*b+1e-3)*P))%P+P)%P;
}
inline LL fast_pow(LL b,LL x,LL P) {
LL res=1;
while (x) {
if (x&1) res=res*b%P;
b=b*b%P;
x>>=1;
}
return res;
}
void DFT(LL c[],LL g,LL M,int opt) {
for (int i=0;i<nn;i++) {
if (i<r[i]) swap(c[i],c[r[i]]);
}
for (int i=1;i<nn;i<<=1) {
LL x=fast_pow(g,(M-1)/(i<<1),M);
for (int j=0;j<nn;j+=(i<<1)) {
LL y=1;
for (int k=0;k<i;k++,y=y*x%M) {
LL z=y*c[i+j+k]%M;
c[i+j+k]=(c[j+k]-z+M)%M;
c[j+k]=(c[j+k]+z)%M;
}
}
}
}
void NTT(LL g,LL M,int p) {
copy(a,a+nn+1,c);copy(b,b+nn+1,d);//防止上次残余影响
DFT(c,g,M,1);DFT(d,g,M,1);
for (int i=0;i<nn;i++) c[i]=(c[i]*d[i])%M;
DFT(c,fast_pow(g,M-2,M),M,-1);
LL inv=fast_pow(nn,M-2,M);
for (int i=0;i<=mm;i++) ans[i][p]=c[i]*inv%M;
}
void Arbitrary_Modulo_NTT() {
LL m1=167772161,m2=998244353,m3=1004535809,g=3;
mm=n+m;nn=1;int step=0;
while (nn<=mm) nn<<=1,step++;
for (int i=0;i<nn;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(step-1));
NTT(g,m1,0);
NTT(g,m2,1);
NTT(g,m3,2);
for (int i=0;i<=mm;i++) {//中国剩余定理合并
LL M=m1*m2,A=(fast_mul(ans[i][0]*m2,fast_pow(m2,m1-2,m1),M)+fast_mul(ans[i][1]*m1,fast_pow(m1,m2-2,m2),M))%M;
LL k=(((ans[i][2]-A)%m3+m3)%m3)*fast_pow(M%m3,m3-2,m3)%m3;
ans[i][3]=(M%GP*k%GP+A%GP)%GP;
}
}
int main() {
n=read(),m=read(),GP=read();
for (int i=0;i<=n;i++) a[i]=read();
for (int i=0;i<=m;i++) b[i]=read();
Arbitrary_Modulo_NTT();
for (int i=0;i<=mm;i++) printf("%lld ",ans[i][3]);
return 0;
}
速度奇慢无比 qaq

\(\begin{cases}x \equiv a_1 \pmod{m_1} \\x \equiv a_2 \pmod{m_2} \end{cases}\)

\(\begin{cases}x=a_1+k_1m_1 \\x=a_2+k_2m_2 \end{cases}\)

\(k_1m_1+(-k_2)m_2=a_2-a_1\)

\(d=\gcd(m_1,m_2), e=a_2-a_1\)

使用扩展欧几里得算法求解 \(x,y\) ,满足 \(xm_1+ym_2=d\)

则有\(x \cdot \frac{e}{d} \cdot m_1+y \cdot \frac{e}{d} \cdot m_2=d \cdot \frac{e}{d}\)

对比可得\(\begin{cases}k_1=x \cdot \frac{e}{d} \\k_2=-y \cdot \frac{e}{d} \end{cases}\)

实际上有多组解\(\begin{cases}k_1=x \cdot \frac{e}{d}+\frac{m_2}{d} \cdot n \\k_2=-y \cdot \frac{e}{d}-\frac{m_1}{d} \cdot n\end{cases} , n\in \mathbb{Z}\)

\(k_1\) 的最小整数解,\(\begin{cases}A=a_1+k_1m_1 \\M=lcm(m_1,m_2)=\frac{m_1m_2}{d} \end{cases}\)

合并成了 \(x\equiv A \pmod{M}\)


对于有些题目,中间运算结果会爆long long。不要偷懒使用__int128,下面是错误示范 ,乖乖打龟速乘。(也不要手写__int128)

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
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
LL a[100005],m[100005];
int n;
LL exgcd(LL a,LL b,LL &x,LL &y) {
if (b==0) {x=1,y=0;return a;}
LL d=exgcd(b,a%b,y,x);y-=(a/b)*x;
return d;
}
inline void excrt() {
LL M=1,A=0;
for (int i=1;i<=n;i++) {
LL x,y,d=exgcd(M,m[i],x,y),mm=m[i]/d;
if ((a[i]-A)%d) {puts("No solution!");return;}
x=(x%mm+mm)%mm;
LL k=(LL)((__int128)(a[i]-A)/d*x%mm+mm)%mm;
LL nM=M*mm;
A=(LL)((A+(__int128)k*M)%nM);
M=nM;
}
printf("%lld",A);
}
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%lld %lld",&m[i],&a[i]);
excrt();
return 0;
}

通用模板:

1
2
3
4
5
6
7
8
9
10
11
12
LL dfs(int p,/*其他状态*/,bool lead/*前导0*/,bool limit/*压上界*/) {
if (p==-1) return 1;//条件和返回值依题目而定
if (!limit && !lead && dp[p][stat]!=-1) return dp[p][stat];
int up=limit?a[p]:9;
LL ans=0;
for (int i=0;i<=up;i++) {
if (...) continue;
ans+=dfs(p-1,/*新状态*/,lead && i==0,limit && i==a[p]);
}
if (!lead && !limit) dp[p][stat]=ans;
return ans;
}

练手题:HDU4507 恨7不成妻
要求维护平方和

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
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long LL;
const int P=1e9+7;
struct node {
LL cnt,sum,sqr;
} dp[25][7][7];
LL pow10[25];
int a[25],nn;
int T;
node dfs(int p,int res1,int res2,bool limit) {
if (p==-1) return (node){(res1 && res2),0,0};
if (!limit && dp[p][res1][res2].cnt!=-1) return dp[p][res1][res2];
int up=limit?a[p]:9;
node ans=(node){0,0,0};
node tmp;
for (int i=0;i<=up;i++) {
if (i==7) continue;
tmp=dfs(p-1,(res1+i)%7,(res2*10+i)%7,limit && (i==a[p]));
ans.cnt+=tmp.cnt;if (ans.cnt>=P) ans.cnt-=P;
ans.sum=(ans.sum+tmp.sum+pow10[p]*i%P*tmp.cnt)%P;
ans.sqr=(pow10[p]*pow10[p]%P*i*i%P*tmp.cnt+2*pow10[p]*i%P*tmp.sum+tmp.sqr+ans.sqr)%P;
}
if (!limit) dp[p][res1][res2]=ans;
return ans;
}
inline LL solve(LL x) {
nn=0;
while (x) {
a[nn++]=x%10;
x/=10;
}
return dfs(nn-1,0,0,1).sqr;
}
int main() {
for (int i=0;i<20;i++) {
for (int j=0;j<7;j++) {
for (int k=0;k<7;k++) dp[i][j][k].cnt=-1;
}
}
pow10[0]=1;
for (int i=1;i<20;i++) pow10[i]=(pow10[i-1]*10)%P;
scanf("%d",&T);
while (T--) {
LL l,r;
scanf("%lld %lld",&l,&r);
printf("%lld\n",((solve(r)-solve(l-1))%P+P)%P);
}
return 0;
}

可以发现所有合法的建站方案,都是两个有且只有一条公共边的三元环拼在一起。题目转化为枚举三元环。
这里给出一种 \(O(m\sqrt{m})\) 的方法。
将所有点分成两类:度大于等于 \(\sqrt{m}\) 的点称为大点,小于 \(\sqrt{m}\) 的点称为小点。
1.枚举三个大点能否组成三元环。
2.枚举小点,以及和它相邻的两个点,能否组成三元环。
判断两点之间有无连边需要使用哈希。

复杂度证明:
1.大点数目不超过 \(\sqrt{m}\) ,枚举复杂度 \(O(\sqrt{m}^3)\)
2.设小点有b条边和它相连。枚举复杂度约为 \(O(\frac{m}{b} b^2)\)
另外可以证明 \(\sqrt{m}\) 是大点小点的最优临界。
上述两步的复杂度都是 \(O(m\sqrt{m})\)

也算一道模板题了。个人比较懒,哈希不写判重,冲突就去买彩票

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
#include<iostream>
#include<cstdio>
#include<cmath>
#define Pair pair<int,int>
#define mp(x,y) make_pair(x,y)
#define rint register int
using namespace std;
typedef long long LL;
const int P=1e7+7;
struct node {
int u,v,ID;
} edge[200005];
int head[50005],vet[400005],nxt[400005],idn[400005],num;
int ha[(int)(1e7+10)];
int bp[50005];
int val[50005],deg[50005],bs;
Pair mx[200005][2];
int n,m;
inline void addedge(int &x,int &y,int &i) {
num++;vet[num]=y;idn[num]=i;nxt[num]=head[x];head[x]=num;
num++;vet[num]=x;idn[num]=i;nxt[num]=head[y];head[y]=num;
}
inline int gethash(int &x,int &y) {
return ((LL)x*(n+1)+y)%P;
}
inline void update(int &v,int &i) {
if (val[v]>mx[i][0].first && v!=mx[i][0].second) {
mx[i][1]=mx[i][0];
mx[i][0]=mp(val[v],v);
}
else if (val[v]>mx[i][1].first && v!=mx[i][0].second) mx[i][1]=mp(val[v],v);
}
int main() {
scanf("%d%d",&n,&m);bs=(int)sqrt((double)m);
for (rint i=1;i<=n;i++) scanf("%d",&val[i]);
for (rint i=1;i<=m;i++) {
int x,y;
scanf("%d%d",&x,&y);edge[i]=(node){x,y,i};
addedge(x,y,i);deg[x]++;deg[y]++;
ha[gethash(x,y)]=ha[gethash(y,x)]=i;
}
for (rint i=1;i<=n;i++) if (deg[i]>=bs) bp[++bp[0]]=i;
for (rint i=3;i<=bp[0];i++) {
for (rint j=2;j<i;j++) {
if (ha[gethash(bp[i],bp[j])]==0) continue;
for (rint k=1;k<j;k++) {
rint x=ha[gethash(bp[i],bp[j])],y=ha[gethash(bp[i],bp[k])],z=ha[gethash(bp[j],bp[k])];
if (y==0 || z==0) continue;
update(bp[i],z);update(bp[j],y);update(bp[k],x);
}
}
}
for (rint i=1;i<=n;i++) {
if (deg[i]>=bs) continue;
for (rint e1=head[i];e1;e1=nxt[e1]) {
for (rint e2=head[i];e2!=e1;e2=nxt[e2]) {
rint j=vet[e1],k=vet[e2],x=ha[gethash(j,k)];
if (x==0) continue;
update(i,x);update(j,idn[e2]);update(k,idn[e1]);
}
}
}
int ans=0;
for (rint i=1;i<=m;i++) {
if (mx[i][1].second==0) continue;
ans=max(ans,(val[edge[i].u]+1)*(val[edge[i].v]+1)+mx[i][0].first*mx[i][1].first);
}
printf("%d\n",ans);
return 0;
}