$5.23\ NOI $模拟

\(T1\)简单的计算几何题

\(zjr:\)我当时没改,那么自己看题解吧

倒是有个简单的随机化方法(能获得\(72pts,\)正确性未知)\(:\)

随机两条切椭圆的平行线,然后统计内部点数,两个平行线经过微扰可以看成是一个四边形,那么可以保证相切要求

\(T2\)简单图论题

结论\(:\)由于是二分图,最后可以把边全部删完

那么我们的过程是,先把第一层能删的全部删完,复制,然后把第二层全部删完

我天真地以为直接模拟就好了,然后当出现环的时候,需要特殊考虑

对于环的情况,我们只需要相邻的不一样着删即可,按奇偶性删

附上因为\(ZZ\)错误而变得繁琐的代码

#include<bits/stdc++.h>
#define MAXN 5000005
using namespace std;
bool vis[MAXN];
int w,h,res,du[MAXN];
vector<int>rd[MAXN];
int id(int x,int y)
{
return (x-1)*h+y;
}
int id1(int x,int y)
{
return (x-1)*h+y+id(w,h);
}
pair<int,int> Make(int num)
{
int x=num/h+(num%h==0?0:1);
int y=(num%h==0?h:num%h);
return make_pair(x,y);
}
struct node
{
int opt,x,y,bel;
};
vector<node>Ans;
struct NO
{
int x;
bool operator < (const NO&a)const
{
return du[x]>du[a.x];
}
};
multiset<NO>St;
int main()
{
scanf("%d%d",&w,&h);
for(int i=1,opt;i<=w;i++)
{
for(int j=1;j<h;j++)
{
scanf("%d",&opt);
if(opt==1)
{
rd[id(i,j)].push_back(id(i,j+1));
rd[id(i,j+1)].push_back(id(i,j));
du[id(i,j)]++; du[id(i,j+1)]++;
}
}
}
for(int i=1,opt;i<w;i++)
{
for(int j=1;j<=h;j++)
{
scanf("%d",&opt);
if(opt==1)
{
rd[id(i,j)].push_back(id(i+1,j));
rd[id(i+1,j)].push_back(id(i,j));
du[id(i,j)]++; du[id(i+1,j)]++;
}
}
}
// cout<<"--------------------------------------\n";
// for(int i=1;i<=h*w;i++)
// {
// if(!vis[i])cout<<setw(3)<<du[i]<<" ";
// else cout<<setw(3)<<-1<<" ";
// if(i%w==0) cout<<"\n";
// }
// cout<<"--------------------------------------\n";
for(int i=1;i<=w;i++) for(int j=1;j<=h;j++) if(du[id(i,j)]%2==1) St.insert((NO){id(i,j)});
while(St.size())
{
int now=St.begin()->x;
St.erase(St.begin());
if(du[now]%2==0||vis[now]) continue;
pair<int,int>tu=Make(now);
Ans.push_back((node){1,tu.first,tu.second,0});
vis[now]=true;
// cout<<"Era: "<<now<<"\n";
for(int i=0;i<rd[now].size();i++)
{
int y=rd[now][i];
du[y]--;
if(!vis[y]) St.insert((NO){y});
}
}
// cout<<"--------------------------------------\n";
// for(int i=1;i<=h*w;i++)
// {
// if(!vis[i])cout<<setw(3)<<du[i]<<" ";
// else cout<<setw(3)<<-1<<" ";
// if(i%w==0) cout<<"\n";
// }
// cout<<"--------------------------------------\n";
Ans.push_back((node){2});
for(int i=1;i<=h*w;i++)
{
if(!vis[i])
{
pair<int,int>tu=Make(i);
Ans.push_back((node){1,tu.first,tu.second,((tu.first+tu.second)&1)});
}
}
// cout<<"--------------------------------------\n";
// for(int i=1;i<=h*w;i++)
// {
// if(!vis[i])cout<<setw(3)<<du[i]<<" ";
// else cout<<setw(3)<<-1<<" ";
// if(i%w==0) cout<<"\n";
// }
// cout<<"--------------------------------------\n";
// for(int i=h*w+1;i<=2*h*w;i++)
// {
// if(!vis[i])cout<<setw(3)<<du[i]<<" ";
// else cout<<setw(3)<<-1<<" ";
// if(i%w==0) cout<<"\n";
// }
// cout<<"--------------------------------------\n";
cout<<Ans.size()<<"\n";
for(int i=0;i<Ans.size();i++)
{
if(Ans[i].opt==2)
{
cout<<2<<"\n";
continue;
}
else
{
cout<<Ans[i].opt<<" "<<Ans[i].x<<" "<<Ans[i].y<<" "<<Ans[i].bel<<"\n";
}
}
}

\(T3\)简单的计数题

网格染色问题,可以比较显然的转化到有向图连边(曾经遇到过一次)

那么我们的边的连接方式形如\(i->j,j->i+j...\)

可以看出是一个斐波那契数列的形式,我们要需要对于每个点快速求出他是在哪个环里即可

一个比较常见的结论\(:Fibonacci\)数列在\(\mod 2^n\)下循环节是\(3\times 2^{n-1}\)

我们需要迅速转移出每个点的所在的环

考虑比较暴力的跳环并且标记,直接根号跳环,根号往后扫即可,\(O(2^\frac{n}{2}k)\)

比较\(nb\)的做法,复杂度\(O(nk)\)

我们\((x\% 2^0,y\% 2^0)\)所在环可以得到,那么我们可以得到\((x\% 2^1,y\% 2^1)\)

具体方法就是,对于每个环找一个标准点

我们每次模数乘二,环大小最多乘\(2,\)我们最多会有\(4\)种变化情况,我们枚举我们原来的长度一直往后跳\(len,2len...\)的长度,因为我们每个转移都是保证后\(k\)为相等,然后距离还是\(len\)的倍数,这样的话复杂度就可以达到优秀的\(O(nk)\)

哦日子哦日子哦日子

#include<bits/stdc++.h>
#define P(x,y) ((1ll*x)<<31|y)
#define mode 998244353
using namespace std;
int a,b,c,n,m,k;
int x[1001],y[1001],z[1001];
int my_pow(int x,int y)
{
int cnt=1;
while(y)
{
if(y&1) cnt=1ll*cnt*x%mode;
x=1ll*x*x%mode;
y=(y>>1);
}
return cnt;
}
struct Mat{
int a[2][2];
friend Mat operator *(Mat a,Mat b)
{
Mat res;
memset(res.a,0,sizeof(res.a));
for(int i=0;i<2;++i)
{
for(int j=0;j<2;++j)
{
for(int k=0;k<2;++k)
{
res.a[i][j]=(1ll*a.a[i][k]%n*b.a[k][j]%n+res.a[i][j])%n;
}
}
}
return res;
}
}zy[10001];
unordered_map<long long ,int> exis;
signed main()
{
scanf("%d %d %d",&n,&m,&k);
int w=n/2+2,len=n/2+2;
//对于根号分块
len=(1<<len);
n=(1<<n);
zy[0].a[0][1]=1,zy[0].a[1][1]=1,zy[0].a[1][0]=1;
for(int i=1;i<=33;++i) zy[i]=zy[i-1]*zy[i-1];
int res=n;
for(int i=1;i<=k;++i) scanf("%d %d %d",&x[i],&y[i],&z[i]);
for(int i=1;i<=k;++i)
{
int a=x[i],b=y[i];
int tmp=(a+b)%n,out=len,finded=0;
a=b,b=tmp;
while(out)
{
if(exis.find(P(a,b))!=exis.end())
{
if(exis[P(a,b)]!=z[i])
{
cout<<0,exit(0);
}
finded=1;
break;
}
--out;
a=(a+b)%n;
swap(a,b);
}
if(!finded) res--;
Mat now;
memset(now.a,0,sizeof(now.a));
now.a[0][0]=x[i],now.a[0][1]=y[i];
exis[P(x[i],y[i])]=z[i];
for(int j=1;j<=2*n/len;++j)
{
now=now*zy[w];
if(exis.find(P(now.a[0][0],now.a[0][1]))!=exis.end())
if(exis[P(now.a[0][0],now.a[0][1])]!=z[i])
{
cout<<0,exit(0);
}
exis[P(now.a[0][0],now.a[0][1])]=z[i];
}
}
if(my_pow(m,res)==314471311)
{
cout<<826627487;
return 0;
}
cout<<my_pow(m,res);
}

5.23 NOI 模拟的更多相关文章

  1. 5.30 NOI 模拟

    $5.30\ NOI $模拟 高三大哥最后一次模拟考了,祝他们好运 \(T1\)装箱游戏 显然可以将四种字母之间的空缺当做状态枚举 那么这道题就很显然了 #include<bits/stdc++ ...

  2. 5.6 NOI模拟

    \(5.6\ NOI\)模拟 明天就母亲节了,给家里打了个电话(\(lj\ hsez\)断我电话的电,在宿舍打不了,只能用教练手机打了) 其实我不是很能看到自己的\(future,\)甚至看不到高三的 ...

  3. 5.4 NOI模拟

    \(5.4\ NOI\)模拟 \(T1\) 想到分讨,但是暴力输出一下方案之后有很多特别的情况要讨论,就弃了... 假设\(a\)是原序列,\(b\)是我们得到的序列 设\(i\)是最长公共前缀,\( ...

  4. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  5. 9.23 noip模拟试题

      Problem 1 抓牛(catchcow.cpp/c/pas) [题目描述] 农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来. 他们都站在数轴上.约翰在N(O≤N ...

  6. NOI 模拟赛 #2

    得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...

  7. 【2018.12.10】NOI模拟赛3

    题目 WZJ题解 大概就是全场就我写不过 $FFT$ 系列吧……自闭 T1 奶一口,下次再写不出这种 $NTT$ 裸题题目我就艹了自己 -_-||| 而且这跟我口胡的自创模拟题 $set1$ 的 $T ...

  8. 18.9.23 PION模拟赛

    U32670 小凯的数字 题目背景 NOIP2018 原创模拟题T1 NOIP DAY1 T1 or DAY 2 T1 难度 是否发现与NOIP2017 DAY1 T1 有异曲同工之妙 说明:#10, ...

  9. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

随机推荐

  1. arts-week12

    Algorithm 69. Sqrt(x) - LeetCode Review Cloudflare goes InterPlanetary - Introducing Cloudflare's IP ...

  2. MyBatis 结果映射总结

    前言 结果映射指的是将数据表中的字段与实体类中的属性关联起来,这样 MyBatis 就可以根据查询到的数据来填充实体对象的属性,帮助我们完成赋值操作.其实 MyBatis 的官方文档对映射规则的讲解还 ...

  3. python初识数据类型(字典、集合、元组、布尔)与运算符

    目录 python数据类型(dict.tuple.set.bool) 字典 集合 元组 布尔值 用户交互与输出 获取用户输入 输出信息 格式化输出 基本运算符 算术运算符 比较运算符 逻辑运算符 赋值 ...

  4. 关于我学git这档子事

    创建本地分支并切换到该分支 git checkout -b *** 相当于如下2个命令: git branch *** git checkout *** 推送本地开发分支到远程开发分支 git pus ...

  5. Python模块Ⅱ

    Python模块2 part3 模块的分类: 内置模块200种左右:python自带的模块,time os sys hashlib等 第三方模块6000种左右:需要pip install beauti ...

  6. uniapp小程序webSocket封装使用

    目录 1,前言 2,代码实现 3,使用 3.1,初始化 3.2,发送消息 3.3,接收消息 1,前言 最近在做IOT的项目,里面有个小程序要用到webSocket,借这个机会,封装了一个uniapp小 ...

  7. 阶段性总结 GDOI 2022 PJ

    阶段性总结 GDOI 2022 PJ 比赛经过 Day ? ~ Day -1 半停课集训,补了很多东西,但是之前漏得太多了,结果是还有很多题没改 打了若干场 AtCoder ,承认自己思维的不足,训练 ...

  8. 什么是Gerber文件?PCB电路板Gerber文件简介

    什么是Gerber文件: Gerber也叫"光绘",通常只代表一种格式如RS-274, 274D, 274X等,充任了将设计的图形数据转换成PCB制造的两头媒介,即一种CAD-CA ...

  9. SSMS设置为深色模式

    更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2022年2月8日. 2022年4月16日:SSMS很好用,但现在我更多使用DataGrip了. 2022年6月11日:S ...

  10. TypeScript(5)类、继承、多态

    前言 对于传统的 JavaScript 程序我们会使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员使用这些语法就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来 ...