2019.3.18考试&2019.3.19考试&2019.3.21考试
2019.3.18
C O D E
T1
树上直接贪心,环上for一遍贪心
哇说的简单,码了将近一下午终于码出来了
感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二次思路又有问题,最后重构了两遍代码
大概先是需要多想,想清楚了不要先考虑细节,果断写+调
废话结束
对于入度大于一且不在环上的点直接贪心留最大的
对于一个完美无瑕的环直接断最小的(指没有被环以外的点指着)
对于入度大于一且在环上的点,先假装它就是普通的入度大于一的点来做并记录每个点是否断了环上的边和断的边中的最大值;最后把没有删边的不完美的环每个单独拿出来,枚举到底断那一条边修正答案
细节不说了,这种题的细节也没啥可说的。。。
(为了避免伤害眼睛已经删掉了调试语句
- #include<cstdio>
- #include<vector>
- #include<cstring>
- #include<algorithm>
- #define vint vector<int>
- #define vit vector<int>::iterator
- using namespace std;
- const int N=;
- int p[N],noww[N],goal[N];
- int rec[N],cst[N],inc[N],col[N];
- int deg[N],aset[N],stk[N],vis[N];
- int cal[N],cut[N],brk[N],spe[N],mae[N];
- int n,dfn,cnt,tot,top; long long ans; vint ve[N],cr[N];
- void Link(int f,int t)
- {
- noww[++cnt]=p[f];
- goal[cnt]=t,p[f]=cnt;
- }
- int Finda(int x)
- {
- return x==aset[x]?x:aset[x]=Finda(aset[x]);
- }
- bool Bigcir()
- {
- int tmp=;
- for(int i=;i<=n;i++)
- {
- if(Finda(i)==i) tmp++;
- if(deg[i]!=) return false;
- }
- return tmp==;
- }
- void DFS(int nde)
- {
- stk[++top]=nde,vis[nde]=dfn;
- for(int i=p[nde],g;i;i=noww[i])
- if(!vis[g=goal[i]]) DFS(g);
- else if(vis[g]==dfn)
- {
- int ori=g,pts=top; tot++;
- while(stk[pts]!=ori)
- {
- int tmp=stk[pts--];
- cr[tot].push_back(tmp);
- col[tmp]=tot,inc[tmp]=true;
- }
- cr[tot].push_back(ori);
- col[ori]=tot,inc[ori]=true;
- }
- top--;
- }
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++) aset[i]=i;
- for(int i=;i<=n;i++)
- {
- scanf("%d%d",&rec[i],&cst[i]);
- Link(i,rec[i]),ve[rec[i]].push_back(i);
- aset[Finda(i)]=Finda(rec[i]),deg[rec[i]]++;
- }
- if(Bigcir()) printf(""),exit();
- else
- {
- cst[n+]=1e9;
- for(int i=;i<=n;i++)
- if(!vis[i]) dfn++,DFS(i);
- for(int i=;i<=n;i++)
- if(deg[i]>&&inc[i])
- {
- int t,o=,c=col[i],kao;
- for(vit it=ve[i].begin();it!=ve[i].end();it++)
- {
- if(!cut[t=*it]&&cst[t]>cst[o]) o=t;
- if(inc[t]) kao=t;
- }
- for(vit it=ve[i].begin();it!=ve[i].end();it++)
- if(!cut[t=*it]&&t!=o)
- {
- cut[t]=true,mae[i]=max(mae[i],cst[t]);
- if(t==kao) brk[c]=true;
- }
- cal[c]=true,spe[i]=true;
- }
- for(int i=;i<=n;i++)
- if(deg[i]>&&!inc[i])
- {
- int t,o=;
- for(vit it=ve[i].begin();it!=ve[i].end();it++)
- if(!cut[t=*it]&&cst[t]>cst[o]) o=t;
- for(vit it=ve[i].begin();it!=ve[i].end();it++)
- if((t=*it)!=o) cut[t]=true,deg[rec[t]]--;
- }
- for(int i=;i<=tot;i++)
- if(!cal[i])
- {
- int t,o=n+;
- for(vit it=cr[i].begin();it!=cr[i].end();it++)
- if(!cut[(t=*it)]&&cst[t]<cst[o]) o=t;
- cut[o]=true,deg[rec[o]]--;
- }
- }
- for(int i=;i<=n;i++)
- if(cut[i]) ans+=cst[i];
- for(int i=;i<=tot;i++)
- if(cal[i]&&!brk[i])
- {
- int t; long long tep=1e18;
- for(vit it=cr[i].begin();it!=cr[i].end();it++)
- if(!spe[rec[t=*it]]) tep=min(tep,ans+cst[t]);
- else tep=min(tep,ans+cst[t]-mae[rec[t]]);
- ans=tep;
- }
- printf("%lld",ans);
- return ;
- }
T2
逐行地每次正反都做一遍DP,记录从哪里吃过来,对应地递归吃后面的
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- const int N=,inf=0x3f3f3f3f;
- int n,m,vis[N][N],dp[N][N];
- char str[N][N];
- void Mini(int &x,int y)
- {
- if(x>y) x=y;
- }
- bool Out(int a,int b)
- {
- return a<||b<||a>n||b>m;
- }
- int DFS(int x,int y,int t)
- {
- if(Out(x,y)) return ;
- int &vs=vis[x][y];
- if(~vs) return vs?:inf;
- vs=; int ret=;
- if(str[x][y]=='Z')
- {
- if(t<) ret+=DFS(x+,y,)+DFS(x,y+,);
- else ret+=DFS(x-,y,)+DFS(x,y-,);
- Mini(ret,inf);
- }
- else
- {
- if(t==||t==) ret+=DFS(x,y+,)+DFS(x-,y,);
- else ret+=DFS(x+,y,)+DFS(x,y-,);
- Mini(ret,inf);
- }
- if(ret!=inf) vs=;
- return ret;
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;i++)
- scanf("%s",str[i]+);
- memset(dp,0x3f,sizeof dp);
- for(int i=;i<=n;i++)
- {
- memset(vis,-,sizeof vis);
- for(int j=,t=;j<=m;j++)
- t+=DFS(i,j,),Mini(t,inf),Mini(dp[i][j],t);
- memset(vis,-,sizeof vis);
- for(int j=m,t=;j;j--)
- t+=DFS(i,j,),Mini(t,inf),Mini(dp[i][j],t);
- }
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- {
- if(dp[i][j]==inf) printf("-1");
- else printf("%d",dp[i][j]);
- j==m?puts(""):putchar(' ');
- }
- return ;
- }
T3
观察到顺序不影响答案,分块打标记
注意分开处理两边零散块是有顺序的
(已经忘掉有分块这个东西了TAT
- #pragma GCC optimize(3)
- #include<queue>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #define vint vector<int>
- #define gint greater<int>
- #define prq priority_queue
- using namespace std;
- const int N=,Sq=;
- int n,m,rd,lp,rp,tg,sqr,tot;
- int sus[N],bel[N],lpt[Sq],rpt[Sq];
- prq<int> mxx[Sq]; prq<int,vint,gint> tag[Sq];
- void Pre()
- {
- sqr=sqrt(n)+,lpt[tot=]=;
- for(int i=;i<=n;i++)
- {
- bel[i]=(i-)/sqr+;
- if(i%sqr==) rpt[tot++]=i,lpt[tot]=i+;
- }
- n%sqr?rpt[tot]=n:tot--;
- }
- void Create(int b)
- {
- mxx[b]=prq<int> ();
- for(int i=lpt[b];i<=rpt[b];i++) mxx[b].push(sus[i]);
- }
- void Release(int b)
- {
- if(!tag[b].empty())
- {
- for(int i=lpt[b];i<=rpt[b];i++)
- if(tag[b].top()<sus[i])
- tag[b].push(sus[i]),sus[i]=tag[b].top(),tag[b].pop();
- }
- tag[b]=prq<int,vint,gint> ();
- }
- int Round(int l,int r,int s)
- {
- if(bel[l]==bel[r])
- {
- int b=bel[l];
- Release(b);
- for(int i=l;i<=r;i++)
- if(s<sus[i]) swap(s,sus[i]);
- Create(b);
- }
- else
- {
- int b1=bel[l],b2=bel[r];
- Release(b1);
- for(int i=l;i<=rpt[b1];i++)
- if(s<sus[i]) swap(s,sus[i]); Create(b1);
- for(int i=b1+;i<=b2-;i++)
- if(s<mxx[i].top())
- {
- int tmp=mxx[i].top(); mxx[i].pop();
- mxx[i].push(s),tag[i].push(s),s=tmp;
- }
- Release(b2);
- for(int i=lpt[b2];i<=r;i++)
- if(s<sus[i]) swap(s,sus[i]); Create(b2);
- }
- return s;
- }
- int main()
- {
- scanf("%d%d",&n,&m),Pre();
- for(int i=;i<=n;i++) scanf("%d",&sus[i]);
- for(int i=;i<=tot;i++) Create(i);
- for(int i=;i<=m;i++)
- {
- scanf("%d%d%d",&lp,&rp,&tg);
- if(lp>rp) tg=Round(lp,n,tg),lp=;
- printf("%d\n",Round(lp,rp,tg));
- }
- return ;
- }
2019.3.19
肥肠爆芡,因为沙茶博主昨天在学校的煞笔食堂吃坏了肚子,所以这场考试咕咕了
开始补档
T1
一开始找x坐标或y坐标最大的点,然后看下一次转向,左转就走极角最大的,右转就走极角最小的
其实扫一遍就可以,然而我傻乎乎地每次都排了个序
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- const int N=;
- struct a{int xp,yp,idx;}o,pt[N],cp[N];
- bool cmp(a x,a y)
- {
- return x.xp==y.xp?x.yp<y.yp:x.xp<y.xp;
- }
- long long Cha(a x,a y)
- {
- return 1ll*(x.xp-o.xp)*(y.yp-o.yp)-1ll*(y.xp-o.xp)*(x.yp-o.yp);
- }
- bool cop(a x,a y)
- {
- return Cha(x,y)<;
- }
- int n,m,vis[N],ans[N]; char str[N];
- void Solve(int p,int l,int r,a q)
- {
- vis[q.idx]=true,ans[p]=q.idx;
- if(p==n) return;
- o=q,sort(cp+l,cp++r,cop);
- if(str[p]=='L') Solve(p+,l,r-,cp[r]);
- else Solve(p+,l+,r,cp[l]);
- }
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- scanf("%d%d",&pt[i].xp,&pt[i].yp),pt[i].idx=i;
- scanf("%s",str+);
- sort(pt+,pt++n,cmp);
- for(int i=;i<=n;i++) cp[i]=pt[i];
- Solve(,,n-,pt[n]);
- for(int i=;i<=n;i++) printf("%d ",ans[i]);
- return ;
- }
T2
推性质题,我们发现每个人感染的是一段区间的人,然后就转成了线段覆盖的方案数,树状数组优化
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #define vint vector<int>
- #define vit vector<int>::iterator
- using namespace std;
- const int N=,mod=1e9+;
- int n,ans,uni[N],spd[N],bit[N],pre[N],suf[N];
- struct a{int pos,spe;}pt[N]; vint ve[N];
- bool cmp(a x,a y){return x.pos<y.pos;}
- void Add(int &x,int y){x+=y; if(x>=mod) x-=mod;}
- void Modify(int x,int y)
- {
- while(x<=n)
- Add(bit[x],y),x+=x&-x;
- return;
- }
- int Query(int x)
- {
- int ret=;
- while(x>)
- Add(ret,bit[x]),x-=x&-x;
- return ret;
- }
- int main()
- {
- register int i;
- scanf("%d",&n);
- for(i=;i<=n;i++)
- scanf("%d%d",&pt[i].pos,&pt[i].spe),uni[i]=pt[i].spe;
- sort(pt+,pt++n,cmp),sort(uni+,uni++n);
- int lth=unique(uni+,uni++n)-uni-;
- for(i=;i<=n;i++) spd[i]=lower_bound(uni+,uni++lth,pt[i].spe)-uni;
- for(i=;i<=n;i++) pre[i]=max(pre[i-],spd[i]);
- for(i=n,suf[n+]=1e9;i;i--) suf[i]=min(suf[i+],spd[i]);
- for(int i=;i<=n;i++) ve[pre[i]].push_back(suf[i]);
- for(int i=,t,tmp;i<=n;i++)
- for(vit it=ve[i].begin();it!=ve[i].end();it++)
- {
- t=*it,tmp=(Query(i)-Query(t-)+(t<)+mod)%mod;
- Modify(i,tmp); if(i==n) Add(ans,tmp);
- }
- printf("%d",ans);
- return ;
- }
T3
这题......
(orz ztb tql)
2019.3.21
T1
容斥/点分治
不想写了摸鱼了咕咕咕了
T2
转化成完全二分图的哈密顿回路,式子随便推推就有了
然后考场推到这里不会去重,搞出来一个整数划分,wsl
去重的方法是我们钦定第一个回路经过左边第一个,然后就有
T3
orz yzh tql
模拟费用流,在每一只鸟进来之后找离这只鸟最近的还有空的点,正确性参考费用流
具体来说要支持树上边权取反和查询到所有合法点的最短路,因为树高只有log暴力爬树DP维护
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- const int N=,inf=1e9;
- int nes[N],gu[N],flw[N],dp[N],bes[N],n,m,ans;
- void Maintain(int nde)
- {
- int ls=*nde,rs=*nde+; dp[nde]=inf;
- if(ls<=n&&dp[ls]+(flw[ls]>=?:-)<dp[nde])
- dp[nde]=dp[ls]+(flw[ls]>=?:-),bes[nde]=bes[ls];
- if(rs<=n&&dp[rs]+(flw[rs]>=?:-)<dp[nde])
- dp[nde]=dp[rs]+(flw[rs]>=?:-),bes[nde]=bes[rs];
- if(nes[nde]&&dp[nde]>=) dp[nde]=,bes[nde]=nde;
- }
- void Pushup(int nde)
- {
- Maintain(nde);
- if(nde!=) Pushup(nde>>);
- }
- void Gu(int nde)
- {
- int x=nde,tmp=,bsf=inf,bsp=,bsn=;
- while(x)
- {
- int tep=tmp+dp[x];
- if(tep<bsf) bsf=tep,bsp=bes[x],bsn=x;
- tmp+=(flw[x]<=?:-),x>>=;
- }
- ans+=bsf,nes[bsp]--;
- int mem1=nde,mem2=bsp;
- while(nde!=bsn) flw[nde]--,nde>>=;
- while(bsp!=bsn) flw[bsp]++,bsp>>=;
- Pushup(mem1),Pushup(mem2);
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;i++) scanf("%d",&nes[i]);
- for(int i=;i<=m;i++) scanf("%d",&gu[i]);
- for(int i=n;i;i--) Maintain(i);
- for(int i=;i<=m;i++) Gu(gu[i]),printf("%d ",ans);
- return ;
- }
2019.3.18考试&2019.3.19考试&2019.3.21考试的更多相关文章
- LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: Root WebApplicationContext: startup date [Sun Jan 13 17:59:19 CST 2019]; root of context hierarch
在运行项目时出现了:LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via ...
- 2019.9.18 csp-s模拟测试46 反思总结
神志不清: 回去休息(x)继续考试(√) 非常爆炸的一次考试.看错题码完T1回去再看发现自己过于幼稚,T2读完题看着16mb的空间秒出正解然后逻辑出现致命失误100pts->0pts,T3看了一 ...
- 2021.8.21考试总结[NOIP模拟45]
T1 打表 由归纳法可以发现其实就是所有情况的总和. $\frac{\sum_{j=1}^{1<<k}(v_j-v_{ans})}{2^k}$ $code:$ 1 #include< ...
- 2021.7.21考试总结[NOIP模拟22]
终于碾压小熠了乐死了 T1 d 小贪心一波直接出正解,没啥好说的(bushi 好像可以主席树暴力找,但我怎么可能会呢?好像可以堆优化简单找,但我怎么可能想得到呢? 那怎么办?昨天两道单调指针加桶,我直 ...
- 9月19号-9月21号丰宁坝上草原行 - 营销系统 - 京东内部论坛 - Powered by Discuz!
9月19号-9月21号丰宁坝上草原行 - 营销系统 - 京东内部论坛 - Powered by Discuz! 9月19号-9月21号丰宁坝上草原行 [复制链接]
- 清北学堂2019.7.18 & 清北学堂2019.7.19
Day 6 钟皓曦 经典题目:石子合并 可以合并任意两堆,代价为数量的异或(^)和 f[s]把s的二进制所对应石子合并成一堆所花代价 枚举s的子集 #include<iostream> u ...
- 开机时自动启动的AutoHotkey脚本 2019年07月08日19时06分
;;; 开机时自动启动的AutoHotkey脚本;; 此脚本修改时间 2019年06月18日20时48分;; 计时器创建代码段 ------------------------------------ ...
- MySQL存储过程-2019/7/18
MySQL 5.0 版本开始支持存储过程. 存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象. 存储过程是为了完成特定功能的SQL语句集,经编 ...
- 2019.8.13 NOIP模拟测试19 反思总结
最早写博客的一次∑ 听说等会儿还要考试[真就两天三考啊],教练催我们写博客… 大约是出题最友好的一次[虽然我还是炸了],并且数据也非常水…忽视第三题的锅的话的确可以这么说.但是T3数据出锅就是你的错了 ...
随机推荐
- Python数据类型-7
什么数据类型. int 1,2,3用于计算. bool:True,False,用户判断. str:存储少量数据,进行操作 'fjdsal' '二哥','`13243','fdshklj' '战三,李四 ...
- Java web错误总结~
1.java程序中没有错,但是项目上面显示一个红叉的解决办法 错误信息: 报Description Resource Path Location Type Java compiler level d ...
- 07-java学习-方法重载-idea集成开发工具学习-项目-模块-包
方法重载的概念? 方法重载的好处? 集成开发工具idea的学习 下载 安装 设置 建项目 导入项目 建模块 导入模块 建包 复制粘贴包 建类 复制粘贴类 运行 调试
- SprngMVC源码学习
运行helloWorld示例进入调试界面. DispatcherServlet:前端控制器 DispatcherServlet.doDispatch(HttpServletRequest, HttpS ...
- book项目分析
需求1:用户注册 需求如下: 1)访问注册页面 2)填写注册信息,提交给服务器 3)服务器应该保存用户 4)当用户已经存在----提示用户注册 失败,用户名已存在 5)当用户不存在-----注册成功 ...
- Java Script正则表达式语法学习
今天在做页面交互验证时,在HTML里面第一反应居然用了Java 处理正则表达式的语法... ---------------------------------题记 学习来源 http://www.ru ...
- 11-Python3从入门到实战—基础之生成器和迭代器
Python从入门到实战系列--目录 切片 Python提供切片(Slice)操作符用来获取列表.元组等数据中的部分元素:如,读取列表 list[m:n]:表示获取m-n区间的元素 list[m:n: ...
- PAT L2-002 链表去重
https://pintia.cn/problem-sets/994805046380707840/problems/994805072641245184 给定一个带整数键值的链表 L,你需要把其中绝 ...
- JavaScript浏览器历史的语法小问题
https://www.w3schools.com/jsref/met_his_back.asp This is the same as clicking the "Back button& ...
- C++拷贝控制
一.拷贝控制操作 当定义一个类时,显示或隐式地指定了此类型的对象在拷贝.赋值和销毁时所执行的操作,通过三个特殊的成员函数来控制这些操作,分别是拷贝构造函数,赋值运算符和析构函数.拷贝构造函数定义了 ...