有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟

吓得我直接文件打错

T1 Skip


设状态$f_i$为最后一次选$i$在$i$时的最优解。有$f_i=max_{j<i}[f_j+a_i-\frac{(j-i)\times (j-i-1)}{2}]$

设$j<k$,对$i$来说,$k$优于$j$,当且仅当$2\times i>\frac{2\times(f_j-f_k)+k^2+k-j^2-j}{k-j}$

斜率优化,$CDQ$分治,先按$a$排序,分治中按$id$排序满足限制,然后维护右下凸包更新答案。

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4
5 namespace IO{
6 inline int read(){
7 char ch=getchar(); int x=0,f=1;
8 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
9 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
10 return x*f;
11 }
12 inline void write(int x,char sp){
13 char ch[20]; int len=0;
14 if(x<0){ putchar('-'); x=~x+1; }
15 do{ ch[len++]=x%10+(1<<4)+(1<<5); x/=10; }while(x);
16 for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
17 }
18 inline int max(int x,int y){ return x<y?y:x; }
19 inline int min(int x,int y){ return x<y?x:y; }
20 inline void swap(int &x,int &y){ x^=y^=x^=y; }
21 inline void chmax(int &x,int y){ x=x<y?y:x; }
22 inline void chmin(int &x,int y){ x=x<y?x:y; }
23 } using namespace IO;
24
25 const int NN=1e5+5;
26 int n,ans,h,t,tmp,q[NN];
27 inline int calc(int x){ return x*(x+1)/2; }
28 struct node{
29 int a,pre,id,f;
30 }f[NN];
31 bool cmp1(node x,node y){ return x.id<y.id; }
32 bool cmp2(node x,node y){ return x.a==y.a?x.id<y.id:x.a<y.a; }
33 bool cmp3(int x,int y,int z){ return (2*(f[z].f-f[x].f)+f[x].pre-f[z].pre)*(f[y].id-f[z].id)>=(2*(f[z].f-f[y].f)+f[y].pre-f[z].pre)*(f[x].id-f[z].id); }
34 bool cmp4(int x,int y,int a){ return 2*(f[y].f-f[x].f)+f[x].pre-f[y].pre>=2*a*(f[x].id-f[y].id); }
35
36 void solve(int l,int r){
37 if(l>=r) return;
38 int mid=l+r>>1;
39 solve(l,mid); h=1; t=0; tmp=l;
40 sort(f+l,f+mid+1,cmp1); sort(f+mid+1,f+r+1,cmp1);
41 for(int i=mid+1;i<=r;i++){
42 while(f[tmp].id<f[i].id&&tmp<=mid){
43 while(h<t&&!cmp3(tmp,q[t],q[t-1])) --t;
44 q[++t]=tmp++;
45 }
46 while(h<t&&!cmp4(q[h+1],q[h],f[i].id)) ++h;
47 if(h>t) continue;
48 chmax(f[i].f,f[q[h]].f+f[i].a-calc(f[i].id-f[q[h]].id-1));
49 }
50 sort(f+mid+1,f+r+1,cmp2);
51 solve(mid+1,r);
52 }
53
54 signed main(){
55 freopen("skip.in","r",stdin);
56 freopen("skip.out","w",stdout);
57 n=read(); ans=-calc(n);
58 for(int i=1;i<=n;i++) f[i].a=read(), f[i].f=f[i].a-calc(i-1), f[i].id=i, f[i].pre=i*i+i;
59 sort(f+1,f+n+1,cmp2); solve(1,n);
60 for(int i=1;i<=n;i++) chmax(ans,f[i].f-calc(n-f[i].id));
61 write(ans,'\n');
62 return 0;
63 }

T1

T2 String


爆搜,记忆化方案数。

参考学长博

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4
5 namespace IO{
6 inline int read(){
7 char ch=getchar(); int x=0,f=1;
8 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
9 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
10 return x*f;
11 }
12 inline void write(int x,char sp){
13 char ch[20]; int len=0;
14 if(x<0){ putchar('-'); x=~x+1; }
15 do{ ch[len++]=x%10+(1<<4)+(1<<5); x/=10; }while(x);
16 for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
17 }
18 inline int max(int x,int y){ return x<y?y:x; }
19 inline int min(int x,int y){ return x<y?x:y; }
20 inline void swap(int& x,int& y){ x^=y^=x^=y; }
21 inline void chmax(int& x,int y){ x=x<y?y:x; }
22 inline void chmin(int& x,int y){ x=x<y?x:y; }
23 } using namespace IO;
24
25 int k,n,base,finl,tim[26],chr[10];
26 char s[1000];
27 map<int,int>f[10];
28
29 inline int bit(int x){ return x?1<<4*x-4:0; }
30 int dfs(int l,int st,int rk,int lst){
31 if(f[lst].find(st)!=f[lst].end()&&f[lst][st]<=rk) return f[lst][st];
32 if(st==finl){
33 if(!rk){ puts(s); exit(0); }
34 return f[lst][st]=1;
35 }
36 int tmp=0,sum=0;
37 for(int i=base;i<26;i++) if(i+'a'!=s[l-1]){
38 ++tim[i]; ++chr[tim[i]]; s[l]=i+'a';
39 if(chr[tim[i]]<=k-tim[i]+1)
40 tmp=dfs(l+1,st+bit(tim[i])-bit(tim[i]-1),rk,tim[i]), rk-=tmp, sum+=tmp;
41 --chr[tim[i]]; --tim[i];
42 }
43 return f[lst][st]=sum;
44 }
45
46 signed main(){
47 freopen("string.in","r",stdin);
48 freopen("string.out","w",stdout);
49 k=read(); n=read();
50 while(k>8){
51 for(int i=1;i<k;i++) putchar(base+'a'), putchar(base+'b');
52 putchar(base+'a'); k-=2; base+=2;
53 }
54 for(int i=1;i<=k;i++) finl|=bit(i);
55 dfs(0,0,n-1,9);
56 puts("-1");
57 return 0;
58 }

T2

T3 Permutation


发现题解是错的,于是花了一下午把它改对了。

首先不难发现可以把问题转化为$n=n+m-k$,$k=m$的情况,因为$m$后的串对答案无影响,且对答案有贡献时后面的串是固定的。设$f_{n,k}$为$n=n,k=k$时的答案。

讨论当前考虑区间的第一个数是否不变。当变化时,设前一行第一个数为$x$,后一行为$x+1$,那么前一行$[2\dots k]$是$n − (k − 2)\dots n$。后一行$[i + 1][2\dots k]$是$x + 2\dots x + k$。

于是答案贡献为$n-k-x$。这部分总答案为$\sum_{j=1}^{n-k}n-j-k$,化简即为$\begin{pmatrix}n-k\\ 2\end{pmatrix}$。

注意$n=1$时答案应为$n-1$,这样算是错的。

设$g_{n,k}=\begin{pmatrix}n-k\\ 2\end{pmatrix}$,那么$f_{n,k}=g_{n,k}+\sum_{j=1}^{n-k+1}f_{n-j,k-1}$,相当于每次枚举第一行相同的值,将第一行去掉。$n-j$表示可取数的个数为$n-j$。

发现$\begin{pmatrix}n\\ m\end{pmatrix}$实际意义可以是将$n+1$有顺序地划分为$m+1$个正整数,那么考虑$g_{x,y}$贡献次数,从$f_{n,k}$到$g_{x,y}$迭代了$k-y$次,第一维一共减了$n-x$,那么它的次数应为将$n-x$划分为$k-y$个正整数的方案,即为$\begin{pmatrix}n-x-1\\ k-y-1\end{pmatrix}$。

考虑枚举$g_{x,y}$中的$y$,计算$2\leq y\leq x\leq k$的总贡献。

第一步枚举$x$相当于将$n − y + 1$划分为$n − x$和$x − y + 1$两个正整数,然后将$n-x$划分为$k-y$个正整数是它的系数,将$x-y+1$划分为$3$个正整数是它的值,合起来考虑,$y$的贡献即为将$n-y+1$划分为$k-y+3$个正整数的方案,也就是$\begin{pmatrix}n-y\\k-y-2\end{pmatrix}$。

因为迭代出的$f_{x,1}$要特殊处理,所以刚才枚举$y$从$2$开始。最后再将$f_{x,1}$的贡献加上即可。

$k=1$要特判。

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4
5 namespace IO{
6 inline int read(){
7 char ch=getchar(); int x=0,f=1;
8 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
9 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
10 return x*f;
11 }
12 inline void write(int x,char sp){
13 char ch[20]; int len=0;
14 if(x<0){ putchar('-'); x=~x+1; }
15 do{ ch[len++]=x%10+(1<<4)+(1<<5); x/=10; }while(x);
16 for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
17 }
18 inline int max(int x,int y){ return x<y?y:x; }
19 inline int min(int x,int y){ return x<y?x:y; }
20 inline void swap(int &x,int &y){ x^=y^=x^=y; }
21 inline void chmax(int &x,int y){ x=x<y?y:x; }
22 inline void chmin(int &x,int y){ x=x<y?x:y; }
23 } using namespace IO;
24
25 const int NN=1e6+5,p=1e9+7;
26 int n,k,m,fac[NN],inv[NN],ans;
27 inline int C(int x,int y){ return x<0||y<0||x<y?0:fac[x]*inv[y]%p*inv[x-y]%p; }
28 inline int qpow(int a,int b){
29 int res=1;
30 while(b){
31 if(b&1) res=res*a%p;
32 a=a*a%p;
33 b>>=1;
34 }
35 return res;
36 }
37
38 signed main(){
39 freopen("perm.in","r",stdin);
40 freopen("perm.out","w",stdout);
41 n=read(); k=read(); m=read(); n=n-k+m; k=m; fac[0]=inv[0]=1;
42
43 for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%p; inv[n]=qpow(fac[n],p-2);
44 for(int i=n-1;i;i--) inv[i]=inv[i+1]*(i+1)%p;
45
46 if(k==1){ write(n-1,'\n'); return 0; }
47 for(int i=2;i<=k;i++) (ans+=C(n-i,k-i+2))%=p;//cout<<ans<<endl;
48 for(int i=2;i<=n;i++){
49 int num=C(n-i-1,k-2);
50 int tmp=i-1;
51 (ans+=num*tmp%p)%=p;//cout<<i<<' '<<num<<' '<<tmp<<endl;
52 }
53 write(ans,'\n');
54 return 0;
55 }

T3

T4 小P的生成树


发现在最后加和的负数的方向向量确定的情况下,每条边的权值是固定的。于是

注意题解里算$tan$式子列反了。。

$code:$

 1 #include<bits/stdc++.h>
2 using namespace std;
3
4 namespace IO{
5 inline int read(){
6 char ch=getchar(); int x=0,f=1;
7 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
8 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
9 return x*f;
10 }
11 inline void write(int x,char sp){
12 char ch[20]; int len=0;
13 if(x<0){ putchar('-'); x=~x+1; }
14 do{ ch[len++]=x%10+(1<<4)+(1<<5); x/=10; }while(x);
15 for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
16 }
17 inline int max(int x,int y){ return x<y?y:x; }
18 inline int min(int x,int y){ return x<y?x:y; }
19 inline void swap(int &x,int &y){ x^=y^=x^=y; }
20 inline void chmax(int &x,int y){ x=x<y?y:x; }
21 inline void chmin(int &x,int y){ x=x<y?x:y; }
22 } using namespace IO;
23
24 const int NN=210;
25 int n,m,f[NN];
26 vector<double>arr;
27 double ans,aa,bb;
28 struct eg{
29 int u,v,a,b;
30 double val;
31 bool operator<(const eg& x)const{ return val>x.val; }
32 }e[NN];
33 int getf(int x){ return f[x]==x?x:f[x]=getf(f[x]); }
34
35 void kruscal(){
36 sort(e+1,e+m+1);
37 aa=0; bb=0;
38 for(int i=1;i<=n;i++) f[i]=i;
39 for(int i=1;i<=m;i++){
40 int fu=getf(e[i].u),fv=getf(e[i].v);
41 if(fu==fv) continue;
42 f[fv]=fu;
43 aa+=e[i].a; bb+=e[i].b;
44 }
45 ans=max(ans,sqrt(aa*aa+bb*bb));
46 }
47 signed main(){
48 freopen("mst.in","r",stdin);
49 freopen("mst.out","w",stdout);
50 n=read(); m=read();
51 for(int i=1;i<=m;i++)
52 e[i].u=read(),e[i].v=read(),e[i].a=read(),e[i].b=read();
53 for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) if(i!=j){
54 double tn=1.0*(e[i].a-e[j].a)/(e[i].b-e[j].b);
55 double ar=atan(tn);
56 arr.push_back(ar), arr.push_back(ar+acos(-1));
57 }
58 sort(arr.begin(),arr.end());
59 for(int i=0;i<arr.size()-1;i++){
60 int j=i+1;
61 double mid=(arr[i]+arr[j])/2;
62 for(int k=1;k<=m;k++) e[k].val=1.0*e[k].a*cos(mid)+1.0*e[k].b*sin(mid);
63 kruscal();
64 }
65 printf("%.6lf",ans);
66 return 0;
67 }

T4

2021.9.17考试总结[NOIP模拟55]的更多相关文章

  1. 2021.6.17考试总结[NOIP模拟8]

    T1 星际旅行 其实就是求两条只走一遍的边的方案数. 考场上第一眼就感觉不可做,后来画了几个图,发现好像只要两个边是相连的就可以只走一遍,居然还真拿了30.. 其实是一道欧拉路的题,把每条非自环的边看 ...

  2. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  3. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  4. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  5. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  6. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  7. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  8. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

  9. 2021.9.9考试总结[NOIP模拟50]

    T1 第零题 神秘结论:从一个点满体力到另一个点的复活次数与倒过来相同. 于是预处理出每个点向上走第$2^i$个死亡点的位置,具体实现可以倍增或二分. 每次询问先从两个点同时向上倍增,都转到离$LCA ...

随机推荐

  1. 关联数组VS索引数组

    关联数组和常规说的数组类似,它包含标量抄数据,可用索引值来单独选择这些数据,和常规数组不同的是, 关联数组的索引值不是非负的整数而是任意的标量袭.这些标量称为百Keys,可以在以后用于检索数组中的数值 ...

  2. 【转】Linux 查看端口占用情况

    Linux 查看端口占用情况可以使用 lsof 和 netstat 命令. lsof lsof(list open files)是一个列出当前系统打开文件的工具. lsof 查看端口占用语法格式: l ...

  3. K8s Master当作Node使用的方法

    1.使用下面的命令操作使得master 可以作为node使用 承载pod kubectl taint nodes --all node-role.kubernetes.io/master- 可能会出现 ...

  4. promise入门基本使用

    Promise入门详解和基本用法   异步调用 异步 JavaScript的执行环境是单线程. 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任 ...

  5. ubuntu中如何切换普通用户、root用户

    1.打开Ubuntu,输入命令:su root,回车提示输入密码,输入密码后提示:认证失败. 2.给root用户设置密码: 命令:sudo passwd root 输入密码,并确认密码. 3.重新输入 ...

  6. win10家庭版 不能远程登录 windows 10 mstsc不可用

    Windows10家庭版的用户,因为系统中没有组策略编辑器,需要修改注册表来实现. 注册表路径:HKLM\Software\Microsoft\Windows\CurrentVersion\Polic ...

  7. linux 下 svn配置;以及多仓库配置

    http://www.linuxidc.com/Linux/2016-01/127679.htm https://blog.csdn.net/mrwu9902/article/details/7869 ...

  8. python继承细节

    不要子类化内置类型 内置类型(由C语言编写)不会调用用户定义的类覆盖的特殊方法. 例如,子类化dict作为测验: class DoppeDict(dict): def __setitem__(self ...

  9. GDOI 2021 退役记

    Day -n 时常想自己不学OI会怎样,经常畏惧自己其实没有心里想的那样有能力,去机房来麻痹自己 从 3.21 始加大频率刷题,复习以前都学会,而现在都被抛在脑后的算法 反正都要退役了,成绩也得鲜亮点 ...

  10. 踩坑系列《十一》完美解决阿里云vod视频点播无法播放音频和视频点播控制台里的媒资库里面的视频无法播放

    刚开始项目部署的时候,音频还是正常播放,后面直接报了 获取m3u8文件失败(manifestLoadError) 的错误,原因是 我的域名 xxx.com 这个域名没有解析到点播提供的CNAME上,所 ...