最早写博客的一次∑

听说等会儿还要考试【真就两天三考啊】,教练催我们写博客…

大约是出题最友好的一次【虽然我还是炸了】,并且数据也非常水…忽视第三题的锅的话的确可以这么说。但是T3数据出锅就是你的错了虽然就算那样我考场上也写不对

我这次考得挺神奇的,T1加个快读由80pts变成AC【再不学快读我就从这里跳下去】,T2写了个玄学nlog二分答案正确性爆炸但是给了我60分,T3暴力dfs给我20分

侥幸程度太大太大了,硬要说的话,我现在本来应该蹲在角落里爆锤自己一通,虽然其实现在也应该这么做。

看看那些差点AK的大佬就会觉得,自己还是没用到爆炸呀。

T1count:

把一棵树分成几个大小一样的连通块,发现只有√n种可能的块的大小,不能整除的大小一定分不出来。然后就有了n√n的做法,枚举每一个因数,然后跑一遍这棵树从底下开始往里塞点,能完整把整棵树塞成大小都为那个因子的几块的话就说明可行,ans++。

实际上这样写常数要大…瞅瞅题解,发现这样一句话:我们可以发现一个可行的方案的最浅的那个点为根的子树的 SIZE 一定可以整除 D。

这话稍微有点绕…我的理解是,每一个正好能分成几块大小为d的连通块的子树或者整棵树,它的size一定可以被d整除。

这不是废话吗?

再往下读:Check 就不用 N 去 check 了,如果有 N/D 个节点的 SIZE 可以整除 D,那么就可行。

嗯?

n/d是把整棵树分成d大小的连通块的块数,那么一个连通块要对应一个size被d整除的子树?形象化地理解一下,就好像一个一个连通块堆叠,每叠一次就对应一个新的最高点,正好是n/d块。堆叠也保证了整块连通。

那么只要跑一遍整棵树记下size,对于n的每个因子都扫一遍这个size数组,只要有n/d个size能被d整除就ans++。虽然也是n√n,但是常数变小了。

不过因为我懒得所以没有改原来的写法,底下的代码是常数大的那种:D

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans,k,flag;
int siz[],vis[],prime[];
int ver[],Next[],head[],tot,tag[],cnt;
int read(){
char ch=getchar();
int val=;
for(;(ch<'')||(ch>'');ch=getchar());
for(;(ch>='')&&(ch<='');val=val*+ch-'',ch=getchar());
return val;
}
void add(int x,int y){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
int dfs(int x,int fa,int limit){
int num=;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa)continue;
num+=dfs(y,x,limit);
if(flag)return ;
}
if((num+)==limit)return ;
else if(num<limit)return num+;
else{
flag=;
return ;
}
}
int main()
{
n=read();
for(int i=,x,y;i<n;i++){
x=read(),y=read();
add(x,y),add(y,x);
}
if(n==){
printf("");
return ;
}
for(int i=;i*i<=n;i++){
if(n%i==){
tag[++cnt]=i;
if(i!=n/i)tag[++cnt]=n/i;
}
}
if(cnt==){
printf("");
return ;
}
else{
ans=;
for(int i=;i<=cnt;i++){
flag=;
dfs(,,tag[i]);
if(!flag)ans++;
}
}
printf("%d",ans);
return ;
}

后面围观的tkj神仙表示如果你把所有size扔进桶里,对于每个d找d,d*2,d*3的size是否存在,最后复杂度会变成nlogn

T2dinner:

我的玄学二分答案:主函数二分答案,check函数直接扫一遍断环成链的n*2的链,能和前面的t一起往一个菜单里塞就继续塞,不能就新开一个菜单。然后走到n以后的每一个位置都和n以前的位置作一下已用菜单数量的差,处理一下+1的细节,最后这个差小于等于m就合法。

正确性显然有问题!没有考虑整个菜单以外的零头情况。

然后这题有一大堆复杂度不对的AC做法,原因是数据过水…比如二分套二分,外面二分时间,里面枚举左端点以后二分地找同一张菜单能覆盖的最远范围,走到下一个位置,然后继续这样找到下一张菜单覆盖的范围…但是这样还是会T,要加一个剪枝,枚举左端点的时候记下已经扫过的左端点的t的和,如果这个和已经大于一张菜单能解决的时间【就是二分答案出来的x】,那么直接return 0回到主函数的二分。原因是,如果左端点扫过的这一段已经大于一张菜单了,那么这个开头对应当前区间的结尾一定强制使用一张菜单,就相当于从1开始做一遍左端点为1右端点为n的check…既然你头一次做这个check的时候就不满足答案,那么再来一次也显然…而如果左端点之前扫过的部分不满足一张菜单,我们仍然可以把当前左端点到右端点的部分看作可以把原来开头扔到后面去考虑能不能凑一张菜单的一个过程【你在说什么】。于是这样剪枝就能让代码跑得飞快地AC了XD

正解是倍增+二分答案。外面的二分不变,里面要先处理一个倍增数组,记录在当前答案下每一个点跳2的次方步最远能跳到哪里。然后枚举左端点,如果跳m步能跳过自己,那么就满足答案。

代码是前面的二分套二分

#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
int t[],maxx,sum,ans,cnt[],b[],flag;
int check(int x){
int num1=;
for(int i=;i<=n;i++){
num1+=t[i];
if(num1>x)return ;
int j=i;
int cnt1=;
flag=;
while(j<=i+n-){
cnt1++;
if(cnt1>m){
flag=;
break;
}
int l=j,r=i+n-;
int ans1=;
while(l<=r){
int mid=(l+r)/;
if(b[mid]-b[j-]<=x){
ans1=mid;
l=mid+;
}
else r=mid-;
}
j=ans1+;
}
if(!flag&&cnt1<=m)return ;
}
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&t[i]);
t[i+n]=t[i];
maxx=max(t[i],maxx);
sum+=t[i];
}
for(int i=;i<=n*;i++){
b[i]=b[i-]+t[i];
}
int l=maxx,r=sum;
while(l<=r){
int mid=(l+r)/;
if(check(mid)){
ans=mid;
r=mid-;
}
else l=mid+;
}
printf("%d",ans);
return ;
}

T3chess:

这题乍一看是个简单bfs,但是仔细读题发现有大坑:只有走过的空格不同才算是不同路径。

于是果断推翻了自己没写多少的代码,折腾不出来正解所以打了个暴力dfs…居然还有20ptsXD

正解是缩边,把不需要的0边全都搞掉。出环一定不优,所以不用考虑边权为1的环。而对于边权为0的环或者链,直接把这个连通块揪出来,把能走到的空地都扔进vector里,然后把这些空地两两连边为1。因为走有敌军的地方不需要计算步数,所以通过敌军连通块能互相达到的点一定距离为1。

然后再对于每个点像它的八个方向正常连距离为1的边。最后最短路计数,跑bfs就可以。因为边权为1,加入队列的顺序就是距离顺序。

比较有意思的是这题坑了好多人一个下午,因为数据有锅。最后衡中那边的巨神们造了一些hack数据,把AC的人的代码都hack掉了。然后大约是std也被hack了吧,总之最后才换上正确数据。

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
int m,n,sx,sy,ex,ey,flag;
int a[][],cnt,c[][],vis[],dis[];
long long f[];
int p[][];
int h[]={,-,-,-,-,,,,};
int l[]={,-,-,,,,,-,-};
vector<int>v;
queue<int>q;
void dfs(int x,int y){
vis[c[x][y]]=;
for(int i=;i<=;i++){
int x2=x+h[i],y2=y+l[i];
if(x2>&&x2<=m&&y2>&&y2<=n&&!vis[c[x2][y2]]){
vis[c[x2][y2]]=;
if(a[x2][y2]!=&&a[x2][y2]!=&&a[x2][y2]!=){
v.push_back(c[x2][y2]);
}
else if(a[x2][y2]==||a[x2][y2]==){
if(a[x2][y2]==)flag=;
dfs(x2,y2);
}
}
}
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
scanf("%d",&a[i][j]);
c[i][j]=++cnt;
if(a[i][j]==)sx=i,sy=j;
if(a[i][j]==)ex=i,ey=j;
}
}
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
if(a[i][j]==&&!vis[c[i][j]]){
flag=;
v.clear();
vis[c[i][j]]=;
dfs(i,j);
for(int i=;i<v.size();i++){
for(int j=;j<v.size();j++){
p[v[i]][v[j]]=p[v[j]][v[i]]=;
}
}
if(flag){
for(int i=;i<v.size();i++){
p[v[i]][c[ex][ey]]=p[c[ex][ey]][v[i]]=;
}
}
for(int i=;i<v.size();i++){
vis[v[i]]=;
}
}
}
}
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
if(a[i][j]==||a[i][j]==)continue;
for(int k=;k<=;k++){
int x2=i+h[k],y2=j+l[k];
if(x2>&&x2<=m&&y2>&&y2<=n){
if(a[x2][y2]!=&&a[x2][y2]!=){
p[c[i][j]][c[x2][y2]]=p[c[x2][y2]][c[i][j]]=;
}
}
}
}
}
memset(vis,,sizeof(vis));
memset(dis,0x3f3f3f3f,sizeof(dis));
dis[c[sx][sy]]=;
vis[c[sx][sy]]=;
f[c[sx][sy]]=;
q.push(c[sx][sy]);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
if(p[u][c[i][j]]&&u!=c[i][j]){
if(dis[c[i][j]]>dis[u]+){
dis[c[i][j]]=dis[u]+;
f[c[i][j]]=f[u];
}
else if(dis[c[i][j]]==dis[u]+){
f[c[i][j]]+=f[u];
}
if(!vis[c[i][j]]){
vis[c[i][j]]=;
q.push(c[i][j]);
}
}
}
}
}
if(dis[c[ex][ey]]<0x3f3f3f3f){
printf("%d\n%lld\n",dis[c[ex][ey]]-,f[c[ex][ey]]);
}
else printf("-1\n");
return ;
}

马上又有新的考试了,大约再好好调整一下状态。其实对于这次的考试…幸运成分太大了,没有什么好说的,只会让我显得非常垃圾。

总的来说这套题还是挺考验思维的,感觉很有意思…自己其实能想到不少东西,大约还是有点进步的吧。

2019.8.13 NOIP模拟测试19 反思总结的更多相关文章

  1. 2019.8.1 NOIP模拟测试11 反思总结

    延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...

  2. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  3. 2019.8.9 NOIP模拟测试15 反思总结

    日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...

  4. 2019.7.29 NOIP模拟测试10 反思总结【T2补全】

    这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...

  5. 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】

    [题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...

  6. 2019.8.12 NOIP模拟测试18 反思总结

    写个博客总是符合要求的对吧 回来以后第一次悄悄参加考试,昨天全程围观… 然后喜提爆炸120分wwwwwwwww T1用了全机房最慢的写法,导致改掉死循环T掉的一个点以后还是死活过不了最后一个点.T2全 ...

  7. 2019.8.10 NOIP模拟测试16 反思总结【基本更新完毕忽视咕咕咕】

    一如既往先放代码,我还没开始改… 改完T1滚过来了,先把T1T2的题解写了[颓博客啊] 今天下午就要走了,没想到还有送行的饯别礼,真是欣喜万分[并没有] 早上刚码完前面的总结,带着不怎么有希望的心情开 ...

  8. 2019.7.27 NOIP模拟测试9 反思总结

    先来整理题目 T1题目大意:给出n个数字和一个质数作为模数,一个变量x初始值为1.进行m次操作,每次让x随机乘上n个数中的一个,问m次操作以后x的期望值. 答案一定可以用分数表示,输出分子乘分母逆元的 ...

  9. 2019.8.7 NOIP模拟测试14 反思总结

    先扔代码 调完自闭网络流了,新一轮考试前看看能不能赶完…… 考得极其爆炸,心态也极其爆炸,真的是认识到自己能力上的不足 思维跑偏,代码能力差 就这样吧,再努力努力,不行就AFO T1旋转子段: 因为我 ...

随机推荐

  1. ros Python找不到msg包的问题解决办法

    https://answers.ros.org/question/113671/catkin-package-cannot-find-own-message-type-python/ 原因是因为.py ...

  2. 第十三章 Odoo 12开发之创建网站前端功能

    Odoo 起初是一个后台系统,但很快就有了前端界面的需求.早期基于后台界面的门户界面不够灵活并且对移动端不友好.为解决这一问题,Odoo 引入了新的网站功能,为系统添加了 CMS(Content Ma ...

  3. BZOJ 2281 消失之物

    ftiasch 有 N 个物品, 体积分别是 W1, W2, -, WN. 由于她的疏忽, 第 i 个物品丢失了. "要使用剩下的 N – 1 物品装满容积为 x 的背包,有几种方法呢?&q ...

  4. 菜鸟安装 CocoaPods

    在 iOS 项目开发中,经常会用到第三方的源代码,CocoaPods 就是为了方便管理这些源码的工具. 在官方教程里面,安装看起来非常简单 $ [sudo] gem install cocoapods ...

  5. JEECMS 自定义标签

    CMS 是”Content Management System” 的缩写,意为” 内容管理系统”. 内容管理系统是企业信息化建设和电子政务的新宠,也是一个相对较新的市场.对于内容管理,业界还没有一个统 ...

  6. java基础之Math类

    Math类概述Math 类包含用于执行基本数学运算的方法,如初等指数.对数.平方根和三角函数. 成员方法 public static int abs(int a):绝对值 public static ...

  7. ASP.NET MVC生命周期与管道模型

      先来熟悉下asp.net请求管道 1.当客户端发送http://localhost:80/home/index请求时 2.首先到达服务端的内核模块HTTP.SYS(它监听80端口),通过访问注册表 ...

  8. STL与泛型编程-练习2-GeekBand

    练习题目: struct Programmer{ Programmer(const int id, const std::wstring name): Id(id), Name(name){ } vo ...

  9. python 编码问题:'ascii' codec can't encode characters in position 的解决方案

    报错: 'ascii' codec can't encode characters in position 8-50: ordinal not in range(128) Python在安装时,默认的 ...

  10. linux为内核新增系统调用

    1.编写hello.c文件,实现系统调用执行函数,如: asmlinkage long sys_helloworld(void){ printk( "helloworld!"); ...