Noip模拟36 2021.8.11
刚题的习惯还是改不了,怎么办???
T1 Dove打扑克
考场上打的动态开点线段树+并查集,考后发现自己像一个傻子,并查集就行。。
这几天恶补数据结构疯了
用树状数组维护后缀和,$siz_i$表示编号为$i$的牌堆的卡牌个数,并使用桶记录一下这种数量级的牌堆的个数
同时使用$set$维护一下还存在的牌堆的编号
在合并的时候按照题目原理对各种维护数组加加减减操作就行,注意在一类数量级的桶没有东西之后,要将$set$中的相应元素删掉
查询的时候遍历$set$中的元素,查询即可。
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 inline int read(){
5 int x=0,f=1; char ch=getchar();
6 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
7 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
8 return x*f;
9 }
10 const int NN=1e5+5;
11 int n,m,fa[NN],tr[NN],r,siz[NN],t[NN];
12 set<int> S;
13 inline int lowbit(int x){return x&(-x);}
14 inline void update(int x,int v){for(;x;x-=lowbit(x)) tr[x]+=v;}
15 inline int query(int x){int ans=0; for(;x<=n;x+=lowbit(x)) ans+=tr[x];return ans;}
16 inline int getfa(int x){return fa[x]=((fa[x]==x)?x:getfa(fa[x]));}
17 inline void merge(int x,int y){
18 int xx=getfa(x),yy=getfa(y);
19 if(xx==yy) return;
20 update(siz[xx],-1);--t[siz[xx]];if(!t[siz[xx]]) S.erase(S.find(siz[xx]));
21 update(siz[yy],-1);--t[siz[yy]];if(!t[siz[yy]]) S.erase(S.find(siz[yy]));
22 ++t[siz[xx]+siz[yy]]; update(siz[xx]+siz[yy],1); if(t[siz[xx]+siz[yy]]==1) S.insert(siz[xx]+siz[yy]);
23 if(siz[xx]>siz[yy]) swap(xx,yy);
24 fa[xx]=yy; siz[yy]+=siz[xx];
25 --r;
26 }
27 namespace WSN{
28 inline short main(){
29 n=read(); m=read(); t[1]=r=n;
30 for(int i=1;i<=n;++i) siz[i]=1,fa[i]=i;
31 update(1,n); S.insert(1);
32 while(m--){
33 int opt=read();
34 if(opt==1){
35 int x=read(),y=read();
36 merge(x,y);
37 continue;
38 }
39 if(opt==2){
40 int c=read();
41 if(!c) printf("%lld\n",r*(r-1)/2);
42 else{
43 int ans=0;
44 for(auto val:S) if(val+c<=n){
45 int res=query(val+c);
46 ans+=res*t[val];
47 if(!res) break;
48 }else break;
49 printf("%lld\n",ans);
50 }
51 continue;
52 }
53 }
54 return 0;
55 }
56 }
57 signed main(){return WSN::main();}
T2 Cicada与排序
考场上居然在大力的刚一道不可做的题,针不戳。
一直在想如何魔改贵并排序的板子,考后看题解发现是$dp$,果然看题没思路就往$dp$想
记录$rk_{i,j}$表示原数组第$i$个数在排列后出现在$j$的概率,那么我们用这个就可以求出答案
其他详情见学长博客
太可恶了,题根本改不完,昨天四道题两道没改。
1 #include<bits/stdc++.h>
2 #define int long long
3 //出现在mid一侧的相同数期望相同
4 using namespace std;
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();}
9 return x*f;
10 }
11 inline void write(int x){
12 char ch[20]; int len=0;
13 if(x<0) x=~x+1, putchar('-');
14 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
15 for(int i=len-1;i>=0;--i) putchar(ch[i]); putchar(' ');
16 }
17 #define yi 0
18 #define er 1
19 const int p=998244353,NN=1005,inv=499122177;
20 int n,a[NN],dp[NN][NN][2],rk[NN][NN];
21 int lt[NN],rt[NN],zz[NN];
22 vector<int> vl[NN],vr[NN];
23 void merge_sort(int le, int ri){
24 if(le==ri) return; int mi=(le+ri)>>1;
25 merge_sort(le,mi); merge_sort(mi+1,ri);
26 for(int i=le;i<=mi;i++) ++lt[a[i]],vl[a[i]].push_back(i);
27 for(int i=mi+1;i<=ri;i++) ++rt[a[i]],vr[a[i]].push_back(i);
28 for(int i=1;i<=1000;i++){
29 for(int l=0;l<=lt[i];l++) for(int r=0;r<=rt[i];r++) dp[l][r][0]=dp[l][r][1]=0;
30 dp[0][0][0]=1;
31 for(int l=0;l<=lt[i];l++) for(int r=0;r<=rt[i];r++){
32 if(l!=lt[i]&&r!=rt[i]){
33 (dp[l+1][r][yi]+=(dp[l][r][yi]+dp[l][r][er])*inv%p)%=p;
34 (dp[l][r+1][er]+=(dp[l][r][yi]+dp[l][r][er])*inv%p)%=p;
35 }
36 else if(l!=lt[i]) (dp[l+1][r][yi]+=dp[l][r][yi]+dp[l][r][er])%=p;
37 else if(r!=rt[i]) (dp[l][r+1][er]+=dp[l][r][yi]+dp[l][r][er])%=p;
38 }
39 for(int j=0;j<lt[i];j++){
40 for(int k=1;k<=lt[i];k++) for(int r=0;r<=rt[i];r++)
41 (zz[k+r]+=rk[vl[i][j]][k]*dp[k][r][0])%=p;
42 for(int k=1;k<=lt[i]+rt[i];k++) rk[vl[i][j]][k]=zz[k],zz[k]=0;
43 }
44 for(int j=0;j<rt[i];j++){
45 for(int k=1;k<=rt[i];k++) for(int l=0;l<=lt[i];l++)
46 (zz[k+l]+=rk[vr[i][j]][k]*dp[l][k][1])%=p;
47 for(int k=1;k<=lt[i]+rt[i];k++) rk[vr[i][j]][k]=zz[k],zz[k]=0;
48 }
49 vl[i].clear(),vr[i].clear(); lt[i]=rt[i]=0;
50 }
51 }
52 void bu_shan_hui_si(){
53 freopen("1.in","r",stdin);
54 freopen("1.out","w",stdout);
55 }
56 namespace WSN{
57 inline short main(){
58 n=read(); for(int i=1;i<=n;i++) a[i]=read();
59 for(int i=1;i<=n;i++) rk[i][1]=1;
60 merge_sort(1,n);
61 for(int i=1;i<=n;i++) ++lt[a[i]];
62 for(int i=0;i<=1000;i++) lt[i]+=lt[i-1];
63 for(int i=1;i<=n;i++){
64 int ans=0;
65 for(int j=1;j<=lt[a[i]]-lt[a[i]-1];j++) (ans+=rk[i][j]*j%p)%=p;
66 write(ans+lt[a[i]-1]);
67 }
68 return 0;
69 }
70 }
71 signed main(){return WSN::main();}
T3 Cicada拿衣服
乱搞题,$AC$全靠勇气。一波巧妙判断搞定$O(n^2)$复杂度
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 #define lid (id<<1)
5 #define rid (id<<1|1)
6 inline int read(){
7 int x=0,f=1; char ch=getchar();
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){
13 char ch[20]; int len=0;
14 if(x<0) x=~x+1, putchar('-');
15 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
16 for(int i=len-1;i>=0;--i) putchar(ch[i]); putchar(' ');
17 }
18 const int NN=1e7+5;
19 int n,k,a[NN];
20 struct SNOWtree{
21 int ll[NN<<2],rr[NN<<2];
22 int maxn[NN<<2],laz[NN<<2];
23 inline void pushup(int id){
24 if(ll[id]==rr[id]) return;
25 maxn[id]=max(maxn[lid],maxn[rid]);
26 }
27 inline void pushdown(int id){
28 if(!laz[id]||ll[id]==rr[id]) return;
29 laz[lid]=max(laz[lid],laz[id]);
30 laz[rid]=max(laz[rid],laz[id]);
31 maxn[lid]=max(maxn[lid],laz[id]);
32 maxn[rid]=max(maxn[rid],laz[id]);
33 laz[id]=0;
34 }
35 void build(int id,int l,int r){
36 ll[id]=l;rr[id]=r; maxn[id]=-1;
37 if(l==r) return;int mid=l+r>>1;
38 build(lid,l,mid); build(rid,mid+1,r);
39 }
40 void update(int id,int l,int r,int val){
41 if(l<=ll[id]&&rr[id]<=r){
42 maxn[id]=max(maxn[id],val);
43 laz[id]=max(laz[id],val);return;
44 }pushdown(id);int mid=ll[id]+rr[id]>>1;
45 if(l<=mid) update(lid,l,r,val);
46 if(r>mid) update(rid,l,r,val);
47 pushup(id);
48 }
49 int query(int id,int pos){
50 if(ll[id]==rr[id]) return maxn[id];
51 pushdown(id); int mid=ll[id]+rr[id]>>1;
52 if(pos<=mid) return query(lid,pos);
53 else return query(rid,pos);
54 }
55 }tr;
56 namespace WSN{
57 inline short main(){
58 n=read();k=read();
59 for(register int i=1;i<=n;++i) a[i]=read();
60 tr.build(1,1,n); int mx,mn,s1,s2,now;
61 for(register int l=1;l<=n;++l){
62 mx=mn=s1=s2=a[l]; now=0;
63 for(register int r=l;r<=n;++r){
64 mx=max(mx,a[r]);
65 mn=min(mn,a[r]);
66 s1=s1|a[r];
67 s2=s2&a[r];
68 if(mn+s1-mx-s2>=k) now=r;
69 else if(r-l+1>100&&n>30000) break;
70 }
71 if(now) tr.update(1,l,now,now-l+1);
72 }
73 for(register int i=1;i<=n;++i){
74 int ans=tr.query(1,i);
75 write(ans);
76 }
77 return 0;
78 }
79 }
80 signed main(){return WSN::main();}
说说正解,$ST$表+链表$list$,比较离谱,头一次接触链表这种东西
也是第一次在代码里面使用这么多的指针,
将柿子倒位置,发现$MAX-MIN$较好维护,直接用$ST$表处理即可
对于$OR-AND$,考虑按位运算的性质,一个范围内的这个值不改变当且仅当同一位置上的数都一样
我们考虑找到这样的一段区间,然后就直接在线段树上插入长度,最后出解即可
使用链表维护这段区间,这段区间合法与否可用是否大于$k$来判断。二分判断
注意边界是上一个链表最右端+1。
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 inline int read(){
5 int x=0,f=1; char ch=getchar();
6 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
7 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
8 return x*f;
9 }
10 inline void write(int x){
11 char ch[20]; int len=0;
12 if(x<0) x=~x+1, putchar('-');
13 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
14 for(int i=len-1;i>=0;--i) putchar(ch[i]); putchar(' ');
15 }
16 const int NN=1e6+5;
17 int n,k,a[NN],lgn,lg[NN],mn[27][NN],mx[27][NN];
18 struct SNOW{int r,mo,ma;};list<SNOW> lis;
19 inline int qmx(int l,int r){int k=lg[r-l+1];return max(mx[k][l],mx[k][r-(1<<k)+1]);}
20 inline int qmn(int l,int r){int k=lg[r-l+1];return min(mn[k][l],mn[k][r-(1<<k)+1]);}
21 inline bool check(list<SNOW>::iterator it,int l,int r){return it->mo-it->ma+qmn(l,r)-qmx(l,r)>=k;}
22 inline void ST_table(){
23 for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
24 for(int j=1;j<=lgn;j++) for(int i=1,t=(1<<j-1);i+(1<<j)-1<=n;i++)
25 mn[j][i]=min(mn[j-1][i],mn[j-1][i+t]),mx[j][i]=max(mx[j-1][i],mx[j-1][i+t]);
26 }
27 struct SNOWtree{
28 #define lid (id<<1)
29 #define rid (id<<1|1)
30 int ans[NN<<2];
31 inline void insert(int id,int l,int r,int L,int R,int val){
32 if(L<=l&&r<=R){ans[id]=max(ans[id],val);return;}
33 int mid=l+r>>1;
34 if(L<=mid) insert(lid,l,mid,L,R,val);
35 if(R>mid) insert(rid,mid+1,r,L,R,val);
36 }
37 inline void print(int id,int l,int r){
38 if(l==r){write(ans[id]);return;}
39 int mid=l+r>>1;
40 ans[lid]=max(ans[lid],ans[id]);
41 ans[rid]=max(ans[rid],ans[id]);
42 print(lid,l,mid); print(rid,mid+1,r);
43 }
44 }tr;
45 namespace WSN{
46 inline short main(){
47 n=read();k=read(); lgn=log(n)/log(2);
48 for(int i=1;i<=n;i++) mx[0][i]=mn[0][i]=a[i]=read();
49 ST_table(); memset(tr.ans,-1,sizeof(tr.ans));
50 for(int R=1;R<=n;R++){
51 for(auto it=lis.begin();it!=lis.end();++it) it->mo|=a[R],it->ma&=a[R];
52 lis.push_back((SNOW){R,a[R],a[R]});
53 for(auto itl=lis.begin(),itr=itl;++itr!=lis.end();)
54 if( (itl->mo-itl->ma) == (itr->mo-itr->ma) )
55 lis.erase(itl),itl=itr;
56 else ++itl;
57 for(auto it=lis.begin();it!=lis.end();++it) if(check(it,it->r,R)){
58 int ll=1,rr=it->r,ans=0;
59 if(it!=lis.begin()) ll=(--it)->r+1,++it;
60 while(ll<=rr){
61 int mid=ll+rr>>1;
62 if(check(it,mid,R)) rr=mid-1,ans=mid;
63 else ll=mid+1;
64 }
65 tr.insert(1,1,n,ans,R,R-ans+1);
66 break;
67 }
68 }
69 tr.print(1,1,n);
70 return 0;
71 }
72 }
73 signed main(){return WSN::main();}
Noip模拟36 2021.8.11的更多相关文章
- Noip模拟74 2021.10.11
T1 自然数 考场上当我发现我的做法可能要打线段树的时候,以为自己百分之百是考虑麻烦了 但还是打了,还过掉了所有的样例,于是十分自信的就交了 正解还真是线段树,真就第一题数据结构 但是包括自己造的小样 ...
- Noip模拟7 2021.6.11
前言 考试时候der展了,T1kmp没特判(看来以后还是能hash就hash),T2搜索细节没注意,ans没清零,130飞到14.... T1 匹配(hash/kmp) 这太水了,其实用个hash随便 ...
- Noip模拟50 2021.9.10
已经好长时间没有考试不挂分的良好体验了... T1 第零题 开场数据结构,真爽 对于这道题首先要理解对于一条链从上向下和从下向上走复活次数相等 (这可能需要晚上躺在被窝里面脑摸几种情况的样例) 然后就 ...
- 2021.8.11考试总结[NOIP模拟36]
T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- Noip模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...
- Noip模拟63 2021.9.27(考场惊现无限之环)
T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...
- Noip模拟61 2021.9.25
T1 交通 考场上想了一个$NPC$.应该吧,是要求出图里面的所有可行的不重复欧拉路 无数种做法都无法解出,时间也都耗在这个上面的,于是就考的挺惨的 以后要是觉得当前思路不可做,就试着换一换思路,千万 ...
随机推荐
- Java中使用jxl.jar将数据导出为excel文件
Java对Excel文件的读写操作可由jxl.jar或poi.jar实现,这里使用jxl.jar完成对Excel文件的导出. 一.将Excel文件导出在本地 步骤: 创建文件 -> 创建 ...
- Dockerfile自动制作Docker镜像(二)—— 其它常用命令
Dockerfile自动制作Docker镜像(二)-- 其它常用命令 前言 a. 本文主要为 Docker的视频教程 笔记. b. 环境为 CentOS 7.0 云服务器 c. 上一篇:Dockerf ...
- yapi 事件创建、修改等接口事件监听
使用的yapi作为接口文档平台.出于业务需求需要对接口创建.修改.删除等事件进行监听. yapi已经实现并预留了这个口子,但是没有找到实现的文档.这里进行简单描述下使用的方式. 一.yapi创建.修改 ...
- jmeter调度器的使用
前言 使用jmeter 做压测的时候,希望对一个接口持续压测 10 分钟或者半小时,可以使用调度器设置持续压测时间. https://www.cnblogs.com/yoyoketang/p/1415 ...
- CI框架 ::集成极光推送
分三步 1:引入类: 2:新建Jpush类: 3:修改源码(PHP5.3.3环境)
- svn的应用
SVN 如何来进行多人协作开发? 在实际工作中,通常是一个小组或者一个团队一起开发同一个项目,不同的人开发不同的功能模块,有一个公共的地方存放项目代码. 如果多个人同时对同一个文件做了修改,比如按照分 ...
- Fillder抓包配置
Faillder设置,完成以下设置后重启Fillder Fillder工具配置 设置端口 端口设置 (根据公司限制使用范围内的端口) 设置是否远程连接 勾选Decrypt HTTPS traffic ...
- 鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么 | 百篇博客分析OpenHarmony源码 | v16.02
百篇博客系列篇.本篇为: v16.xx 鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪 ...
- ssh 登录远程服务器--config配置
一.config 配置案列 Host master HostName: 39.105.61.1 Port 22 User root IdentityFile <id_rsa> 二.配置讲解 ...
- CF1446F-Line Distance【计算几何,树状数组,二分】
正题 题目链接:https://www.luogu.com.cn/problem/CF1446F 题目大意 给出\(n\)个点,求所有点对构成的直线中与原点距离第\(k\)小的距离 \(2\leq n ...