Noip模拟74 2021.10.11
T1 自然数
考场上当我发现我的做法可能要打线段树的时候,以为自己百分之百是考虑麻烦了
但还是打了,还过掉了所有的样例,于是十分自信的就交了
正解还真是线段树,真就第一题数据结构
但是包括自己造的小样例还是大样例我都少考虑了一个问题,就是元素可能相等
所以估分$100$实际只有$68$,以后造样例的时候还是要根据题目搞一些极端的数据出来
先说暴力吧,考虑到$a_i$的值域是拿来吓唬人的,因为$mex$不可能超过$2e5$
所以大于边界的值直接跳过不考虑,这个条件比较关键
那么我们使用经典指针
$pos$指向答案,初始指向$0$,枚举左端点扫右端点
那么每次使用栈记录遍历到的$a_i$值,以便清空时更快
显然只有当扫到的点的值把当前$pos$的位置占了之后$pos$才会移动
所以维护指针的算法就出来了,$O(n^2)$
1 for(int l=1;l<=n;l++){
2 int pos=0,r=l;
3 while(vis[pos]) ++pos;
4 while(r<=n){
5 if(a[r]<NN&&(!vis[a[r]])) vis[a[r]]=1,stk[++top]=a[r];
6 while(vis[pos]) ++pos;
7 ++r; ans+=pos;
8 }
9 while(top) vis[stk[top--]]=0;
10 }
11 write(ans);
TLE 50
那么考虑优化右端点移动的过程
先把$1~[1,N]$的所有区间的贡献预处理出来,用一个数组记录,为$h[r]$
拿我自己造的优秀$hack$数据举例
5
1 2 0 3 5 //其实还有 5 2 1 0 3 5 && 5 3 1 0 2 5
以上三个答案分别是$17,20,21$
以第二个来说的话,预处理出的数组为$0,0,3,4,4$,
然后考虑每次删除一个左端点,发现贡献会依次变为
$0,2,2,2$、$1,1,1$、$0,0$、$0$,然后你可以再试一下有重复数字的数组
发现$a[l]$(当前要删的左端点值)会把第一个大于它的数($h$数组里的)到下一个它出现($a$数组里的)之间的所有数覆盖成$a[l]$这个值
想一想的话也很好理解(基于你打了双指针移动的暴力)
所以你记录一个$nxt$数组,线段树上维护一个$sum,minn$就可以解决问题了,找位置用线段树二分
因为我是没发现有重复,所以直接更新到$n$他是对的,于是我直接在没修改的$h$数组上面二分找位置也是对的,
因为每次更新只会往小里更新,而且更新之后数组还是单调不降。
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 namespace AE86{
5 inline int read(){
6 int x=0,f=1;char ch=getchar();
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();}return x*f;
9 }inline void write(int x,char opt='\n'){
10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int NN=400005;
15 int n,a[NN],ans,sum,h[NN],nxt[NN];
16 int vis[NN],tag[NN];
17 struct SNOWtree{
18 #define lid (id<<1)
19 #define rid (id<<1|1)
20 int ll[NN<<2],rr[NN<<2];
21 int sum[NN<<2],laz[NN<<2],mn[NN<<2];
22 inline void pushup(int id){
23 if(ll[id]==rr[id]) return;
24 sum[id]=sum[lid]+sum[rid];
25 mn[id]=min(mn[lid],mn[rid]);
26 }
27 inline void pushdown(int id){
28 if(ll[id]==rr[id]||laz[id]==-1) return;
29 laz[lid]=laz[rid]=laz[id];
30 mn[rid]=mn[lid]=laz[id];
31 sum[lid]=laz[id]*(rr[lid]-ll[lid]+1);
32 sum[rid]=laz[id]*(rr[rid]-ll[rid]+1);
33 laz[id]=-1;
34 }
35 inline void build(int id,int l,int r){
36 ll[id]=l; rr[id]=r; laz[id]=-1; mn[id]=0x3fffffff;
37 if(l==r) return mn[id]=sum[id]=h[l],void();
38 int mid=l+r>>1;
39 build(lid,l,mid); build(rid,mid+1,r);
40 pushup(id);
41 }
42 inline void change(int id,int pos,int v){
43 if(ll[id]==rr[id]) return mn[id]=sum[id]=v,void();
44 pushdown(id);int mid=ll[id]+rr[id]>>1;
45 if(pos<=mid) change(lid,pos,v);
46 else change(rid,pos,v);
47 pushup(id);
48 }
49 inline void update(int id,int l,int r,int v){
50 if(l<=ll[id]&&rr[id]<=r){
51 sum[id]=v*(rr[id]-ll[id]+1);
52 mn[id]=laz[id]=v; return;
53 }pushdown(id);int mid=ll[id]+rr[id]>>1;
54 if(l<=mid) update(lid,l,r,v);
55 if(r>mid) update(rid,l,r,v);
56 pushup(id);
57 }
58 inline int lower_bound_(int id,int pos){
59 if(ll[id]==rr[id]){
60 if(mn[id]>=pos) return ll[id];
61 return n+1;
62 }pushdown(id);
63 if(mn[rid]<pos) return lower_bound_(rid,pos);
64 else return min(lower_bound_(lid,pos),ll[rid]);
65 return n+1;
66 }
67 }tr;
68 namespace WSN{
69 inline short main(){
70 // freopen("in.in","r",stdin);
71 // freopen("bao.out","w",stdout);
72 freopen("mex.in","r",stdin);
73 freopen("mex.out","w",stdout);
74 n=read();
75 for(int i=1;i<=n;i++) a[i]=read();
76 int pos=0;
77 for(int r=1;r<=n;r++){
78 if(a[r]<NN&&(!vis[a[r]])) vis[a[r]]=1;
79 while(vis[pos]) ++pos;
80 sum+=pos; h[r]=pos; nxt[r]=n+1;
81 }
82 memset(vis,0,sizeof(vis));
83 for(int i=1;i<=n;i++) if(a[i]<NN) nxt[vis[a[i]]]=i,vis[a[i]]=i;
84 // for(int i=1;i<=n;i++) cout<<nxt[i]<<" ";cout<<endl;
85 // cout<<sum<<endl;
86 ans=sum; tr.build(1,1,n);
87 for(int l=1;l<n;l++){
88 tr.change(1,l,0);
89 pos=tr.lower_bound_(1,a[l]+1);
90 // cout<<pos<<" "<<nxt[pos]<<endl;
91 if(pos<nxt[l]) tr.update(1,pos,nxt[l]-1,a[l]);
92 ans+=tr.sum[1];
93 }
94 write(ans);
95 return 0;
96 }
97 }
98 signed main(){return WSN::main();}
99 // cout<<a[l-1]<<" "<<pos<<" "<<tr.query(1,l,pos-1)<<" "<<(n-pos+1)*a[l-1]<<endl;
T2 钱仓
按照$c_i-1$的前缀和找到最长的$\geq 0$的一段,记一个起点$S$然后倒着贪心把有东西的点上的东西能向后移动就向后移动
维护一个队列就行
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 namespace AE86{
5 inline int read(){
6 int x=0,f=1;char ch=getchar();
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();}return x*f;
9 }inline void write(int x,char opt='\n'){
10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int NN=2e5+5;
15 int n,c[NN],S,sum;
16 int q[NN],l,r;
17 namespace WSN{
18 inline short main(){
19 // freopen("in.in","r",stdin);
20 // freopen("bao.out","w",stdout);
21 freopen("barn.in","r",stdin);
22 freopen("barn.out","w",stdout);
23 n=read();
24 for(int i=1;i<=n;i++) c[n+i]=c[i]=read();
25 for(int i=1;i<=n;i++){
26 sum+=c[i]-1;
27 if(sum<0) S=i+1,sum=0;
28 }
29 l=1,r=sum=0;
30 for(int i=S+n-1;i>=S;i--){
31 if(!c[i]) q[++r]=i;
32 else{
33 while(l<=r && c[i]){
34 int pos=q[l++]; --c[i];
35 sum+=(pos-i)*(pos-i);
36 }
37 if(!c[i]) q[++r]=i;
38 }
39 } write(sum);
40 return 0;
41 }
42 }
43 signed main(){return WSN::main();}
T3 游戏
设$a_n,b_n$分别为剩下$n$个石子时$A$先手获胜的概率和$B$先手获胜的概率
发现$n$为奇数的时候两人都想拿,偶数时都不想
那么有两个递推方程
$a_{n+1}=p(1-q)a_n+(1-p)b_n+(1-p)(1-q)a_{n+1}$
$b_{n+1}=q(1-p)b_n+(1-q)a_n+(1-p)(1-q)b_{n+1}$
然后化简按照奇数偶数转移就有$76$分
然后把转移系数构建矩阵就可以了
具体就是把奇数矩阵先和偶数矩阵乘在一起,然后做$\frac{n}{2}$次转移
如果$n$是奇数再来一次奇数矩阵,
最后直接输出第二行第一列的值即可,因为$a_0=0,b_0=1$,转移只有那一个有贡献
复杂度$O(8log_nT)$
1 #include<stdio.h>
2 #include<algorithm>
3 #include<cstring>
4 #define int long long
5 using namespace std;
6 const int mod=1e9+7,inv=571428574;
7 int T,n,p,q;
8 inline int qmo(int a,int b,int ans=1){
9 int c=mod;for(;b;b>>=1,a=a*a%c)if(b&1)ans=ans*a%c;
10 return ans;
11 }
12 namespace Matrix{
13 struct Ma{
14 int m[3][3];
15 Ma(){memset(m,0,sizeof(m));}
16 inline void pre(){m[1][1]=m[2][2]=1;}
17 inline void print(){printf("%lld %lld\n%lld %lld\n",m[1][1],m[1][2],m[2][1],m[2][2]);}
18 Ma operator*(const Ma&a)const{
19 Ma res;
20 for(int i=1;i<=2;i++)
21 for(int j=1;j<=2;j++)
22 for(int k=1;k<=2;k++)
23 (res.m[i][j]+=m[i][k]*a.m[k][j]%mod)%=mod;
24 return res;
25 }
26 };
27 inline Ma ksm(Ma a,int b){
28 Ma ans;ans.pre();
29 for(;b;b>>=1,a=a*a)if(b&1)ans=ans*a;
30 return ans;
31 }
32 int c[3];
33 inline void mul(int a[3],Ma b){
34 memset(c,0,sizeof(c));
35 for(int i=1;i<=2;i++)
36 for(int j=1;j<=2;j++)
37 (c[i]+=a[j]*b.m[j][i]%mod)%=mod;
38 memcpy(a,c,sizeof(c));
39 }
40 }using namespace Matrix;
41 namespace TASK{
42 inline void task1(){
43 int P=p*inv%mod,Q=q*inv%mod;
44 printf("%lld\n",P*qmo((1-((1-P+mod)%mod)*((1-Q+mod)%mod)%mod+mod)%mod,mod-2)%mod);
45 }
46 inline void task2(){
47 int P=p*inv%mod,Q=q*inv%mod,v3=qmo(3,mod-2);Ma g;
48 g.m[2][2]=g.m[1][1]=v3;g.m[2][1]=g.m[1][2]=2*v3%mod;
49 g=ksm(g,n);printf("%lld\n",g.m[2][1]);
50 }
51 int a[1005],b[1005];
52 inline void task3(){
53 memset(a,0,sizeof(a)); memset(b,0,sizeof(b));
54 a[0]=0; b[0]=1;
55 int P=p*inv%mod,Q=q*inv%mod;
56 for(int i=1;i<=n;i++){
57 if((i&1)==0){
58 int tmp=qmo((1-P*Q%mod+mod)%mod,mod-2);
59 a[i]=P*((1-Q+mod)%mod)%mod*tmp%mod*a[i-1]%mod+(1-P+mod)%mod*tmp%mod*b[i-1]%mod;
60 b[i]=(1-Q+mod)%mod*tmp%mod*a[i-1]%mod+Q*((1-P+mod)%mod)%mod*tmp%mod*b[i-1]%mod;
61 }else{
62 int tmp=qmo((1-((1-P+mod)%mod)*((1-Q+mod)%mod)%mod+mod)%mod,mod-2);
63 a[i]=(1-P+mod)%mod*Q%mod*tmp%mod*a[i-1]%mod+P*tmp%mod*b[i-1]%mod;
64 b[i]=Q*tmp%mod*a[i-1]%mod+(1-Q+mod)%mod*P%mod*tmp%mod*b[i-1]%mod;
65 }
66 }
67 printf("%lld\n",a[n]%mod);
68 }
69 }using namespace TASK;
70 int dp[3];
71 namespace WSN{
72 inline short main(){
73 freopen("game.in","r",stdin);
74 freopen("game.out","w",stdout);
75 scanf("%lld",&T);
76 while(T--){
77 scanf("%lld%lld%lld",&n,&p,&q);
78 Ma f,g;
79 int P=p*inv%mod,Q=q*inv%mod;
80 int tmp=qmo((1-P*Q%mod+mod)%mod,mod-2);
81 f.m[1][1]=P*((1-Q+mod)%mod)%mod*tmp%mod;
82 f.m[1][2]=(1-Q+mod)%mod*tmp%mod;
83 f.m[2][1]=(1-P+mod)%mod*tmp%mod;
84 f.m[2][2]=Q*((1-P+mod)%mod)%mod*tmp%mod;
85 tmp=qmo((1-((1-P+mod)%mod)*((1-Q+mod)%mod)%mod+mod)%mod,mod-2);
86 g.m[1][1]=(1-P+mod)%mod*Q%mod*tmp%mod;
87 g.m[1][2]=Q*tmp%mod;
88 g.m[2][1]=P*tmp%mod;
89 g.m[2][2]=(1-Q+mod)%mod*P%mod*tmp%mod;
90 Ma ret=g*f; int b=n/2;dp[1]=0;dp[2]=1;
91 while(b){
92 if(b&1) mul(dp,ret);
93 b>>=1; ret=ret*ret;
94 }
95 if(n&1) mul(dp,g);
96 printf("%lld\n",dp[1]%mod);
97 }
98 return 0;
99 }
100 }
101 signed main(){return WSN::main();}
T4 Sanrd
咕咕咕
Noip模拟74 2021.10.11的更多相关文章
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- Noip模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...
- Noip模拟77 2021.10.15
T1 最大或 $T1$因为没有开$1ll$右移给炸掉了,调了一年不知道为啥,最后实在不懂了 换成$pow$就过掉了,但是考场上这题耽误了太多时间,后面的题也就没办法好好打了.... 以后一定要注意右移 ...
- Noip模拟36 2021.8.11
刚题的习惯还是改不了,怎么办??? T1 Dove打扑克 考场上打的动态开点线段树+并查集,考后发现自己像一个傻子,并查集就行.. 这几天恶补数据结构疯了 用树状数组维护后缀和,$siz_i$表示编号 ...
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- Noip模拟81 2021.10.20
T1 语言 比较简单的题,然后就瞎写了,所以考场上就我一个写了线段树的,所以我的常数.... 所以就枚举动词的位置,找前面后面有没有出现$4$即可 1 #include<bits/stdc++. ...
- Noip模拟83 2021.10.26
T1 树上的数 有手就能在衡中$OJ$上过,但是$WaitingCoders$不行,就是这样 必须使用$O(n)$算法加上大力卡常,思路就是找子树内没更新的更新,更新过了直接$return$ 1 #i ...
- Noip模拟80 2021.10.18
预计得分:5 实际得分:140?????????????? T1 邻面合并 我考场上没切掉的大水题....(证明我旁边的cty切掉了,并觉得很水) 然而贪心拿了六十,离谱,成功做到上一篇博客说的有勇气 ...
- Noip模拟79 2021.10.17(题目名字一样)
T1 F 缩点缩成个$DAG$,然后根据每个点的度数计算期望值 1 #include<cstdio> 2 #include<cstring> 3 #include<vec ...
随机推荐
- CSS004. 自定义滚动条样式(webkit)
CSS /* 滚动条宽度 */ ::-webkit-scrollbar { width: 6px; } /* 轨道样式 */ ::-webkit-scrollbar-track { backgroun ...
- LVS负载均衡集群--DR模式部署
目录: 一.LVS-DR数据包流向分析 二.DR 模式的特点 三.LVS-DR中的ARP问题 四.DR模式 LVS负载均衡群集部署 一.LVS-DR数据包流向分析 1.为方便进行原理分析,将clien ...
- elementUI 表格 table 的表头错乱问题
页面中多组件开发时,如果页面中有表格的,table表格头出现表头错乱 // 全局设置1 body .el-table th.gutter{ 2 display: table-cell!importan ...
- 手把手教你 Docker Compose安装DOClever
一.什么是Docker Compose以及Docker Compose的安装和使用 查看我的另外一篇博客:Docker Compose的安装和使用 二.DOClever是什么 DOClever是一个可 ...
- promise入门基本使用
Promise入门详解和基本用法 异步调用 异步 JavaScript的执行环境是单线程. 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任 ...
- requests接口自动化-excel参数化
在数据量大的时候,需要使用文件参数化. excel文件是其中一种. 安装xlrd读取excel文件.(这里是在pycharm安装) 发现选择豆瓣安装失败,阿里云安装成功. 准备excel文件,放在te ...
- jzoj4496-[GDSOI2016]互补约数【莫比乌斯反演】
正题 题目链接:https://gmoj.net/senior/#main/show/4496 题目大意 给出\(n\),定义 \[f(i)=\sum_{d|i}gcd(d,\frac{i}{d}) ...
- CF346E-Doodle Jump【类欧】
正题 题目链接:https://www.luogu.com.cn/problem/CF346E 题目大意 给出\(a,n,p,h\),在每个\(ax\%p(x\in[0,n])\)的位置有一个关键点, ...
- Redis对象
概述 Redis并没有使用基础数据结构去实现键值数据库,而是基于数据结构封装了一个个对象. 类型和编码 由于Redis是键值数据库,所以每次存储数据时,至少包含两个对象,即K.V对应的对象.其数据结构 ...
- MacOS上通过虚拟机搭建基础CentOS7系统环境
MacOS上通过虚拟机搭建基础CentOS7系统环境 尽管从Mac的Terminal可以看出,macOS与UNIX.Linux或多或少都有血缘关系(shell.bash等),但是在mac进行Linux ...