NOIP模拟64
T1 三元组
解题思路
一看题面,好像是一道数学题,但不完全是,或者说根本不是。。。
比较好想到的是 \(\mathcal{O}(n^2)\) 和 \(\mathcal{O}(nk)\) 的做法,然后就有了 60pts。。。
观察范围对于每一个 \(b\) 而言 \(a+b^2\) 的范围就是 \([1+b^2,b+b^2]\) 。
充分利用 \(a\le b\le c\) 这个条件,枚举 \(c\) 然后就对于每一个新加入的 \(c\) , \(a,b\) 的范围也会相应的扩大。
因此可以维护树状数组,对于取模之后的区间进行区间修改,然后单点查询每一个 \(c^3\) 的贡献就好了。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e5+10;
int Test,ans,n,p;
struct BIT
{
int tre[N];
void clear(){memset(tre,0,sizeof(tre));}
int lowbit(int x){return x&(-x);}
void insert(int x,int val){for(int i=x+1;i<=p;i+=lowbit(i))tre[i]+=val;}
int query(int x){int sum=0;for(int i=x+1;i;i-=lowbit(i))sum+=tre[i];return sum;}
void insert(int l,int r,int val){insert(l,val);insert(r+1,-val);}
}T;
void solve()
{
n=read(); p=read(); ans=0; T.clear();
for(int i=1;i<=n;i++)
{
int l=(1+i*i)%p,r=(i+i*i)%p,temp=i/p;
T.insert(0,p-1,temp);
if(i%p&&l<=r) T.insert(l,r,1);
else if(i%p&&l>r) T.insert(l,p-1,1),T.insert(0,r,1);
ans+=T.query(i*i*i%p);
}
printf("%lld\n",ans);
}
signed main()
{
freopen("exclaim.in","r",stdin); freopen("exclaim.out","w",stdout);
Test=read(); for(int i=1;i<=Test;i++) printf("Case %lld: ",i),solve();
return 0;
}
T2 简单的字符串
解题思路
打了一种假做法,但是好像不是特别可以被卡掉(吸氧的前提下)
\(n^3\) 的做法加上字符集优化(也就是无序 Hash 即可)。
当然为了防止被 Hack ,于是我加了一个 map
记忆化一下
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=5e3+10;
const ull base=133331ull;
int n,ans,s[N];
ull has,has2,hs[N],p[N],pre[N];
map< pair<ull,ull> , bool > mp;
ull power(ull x,int y)
{ull temp=1;while(y){if(y&1) temp=temp*x;x=x*x; y>>=1;}return temp;}
ull get(int l,int r){return pre[r]-pre[l-1]*p[r-l+1];}
signed main()
{
freopen("s.in","r",stdin); freopen("s.out","w",stdout);
n=read(); p[0]=1;
for(int i=1;i<=n;i++)
s[i]=read(),pre[i]=pre[i-1]*base+s[i],
p[i]=p[i-1]*base,hs[i]=hs[i-1]+power(s[i],base);
for(int len=2;len<=n;len+=2)
for(int l=1;l+len-1<=n;l++)
{
int r=l+len-1,mid=(l+r)>>1; has=pre[r]-pre[mid]*p[len/2]; has2=pre[mid]-pre[l-1]*p[len/2];
if(hs[r]-hs[mid]!=hs[mid]-hs[l-1]) continue;
if(has==has2||mp.find(make_pair(has,has2))!=mp.end()){ans++;continue;}
for(int i=l;i<=mid;i++)
{
ull ha1=get(l,i),ha2=get(i+1,mid),ha=ha1+ha2*p[i-l+1];
if(has==ha)
{
if(has>has2) swap(has,has2);
mp.insert(make_pair(make_pair(has,has2),true));
ans++;break;
}
}
}
printf("%lld",ans);
return 0;
}
T3 环路
解题思路
矩阵快速幂
矩阵 \(A_{i,j}\) 表示 i 到 j 是否有连边,也就是初始读入的矩阵, B 为单位矩阵。
于是我们就可以快速利用矩阵快速幂算出每个点在 k 步可以到达的点,但是这样显然需要记录到每一个状态的答案。
考虑建假点,对于 \(i\) 点建一个 \(i+n\) 作为假点,每个点向相对应的假点连一条边,同样的假点也要向自己连边。
最后答案就是 从 \(i\) 到 \(i+n\) 的方案数减去 \(n\) 也就是没有移动的方案数
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=210;
int n,m,mod,ans;
char ch[N];
struct Square
{
int a[N][N];
void clear(){memset(a,0,sizeof(a));}
Square friend operator * (Square x,Square y)
{
Square z; z.clear();
for(int i=1;i<=2*n;i++)
for(int j=1;j<=2*n;j++)
for(int k=1;k<=2*n;k++)
z.a[i][j]+=x.a[i][k]*y.a[k][j]%mod;
for(int i=1;i<=2*n;i++)
for(int j=1;j<=2*n;j++)
z.a[i][j]%=mod;
return z;
}
}A,B;
void power(Square &x,Square e,int y){while(y){if(y&1)x=x*e;e=e*e;y>>=1;}}
signed main()
{
freopen("tour.in","r",stdin); freopen("tour.out","w",stdout);
n=read();
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1); B.a[i][i]=B.a[i+n][i+n]=A.a[i][i+n]=A.a[i+n][i+n]=1;
for(int j=1;j<=n;j++) A.a[i][j]=(ch[j]=='Y');
}
m=read(); mod=read(); power(B,A,m);
for(int i=1;i<=n;i++) ans+=B.a[i][i+n];
printf("%lld",(ans-n+mod)%mod);
return 0;
}
T4 过河
解题思路
很玄学的一道题,从考试开始到结束看这个题的思路只有 模拟,模拟,再模拟,然后喜提 0pts
对于 60pts 的做法直接暴力枚举在运送神猪(就是所有三元组都有的猪)前后所运送的两只猪判断剩下的关系是否是二分图就好了。
进行一些优化只枚举一只,查看剩下的图是否可以通过删掉一个点成为二分图。
因此我们可以高出一个 DFS 树,一个合法的点的充要条件就是被所有奇数长度的环经过,并且不可以存在一个奇数环或者偶数环一段在子树中,另一端在当前点的上方。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=3e3+10,INF=1e18;
int T,n,m,jud,flag,pos,all,dep[N],fa[N],odd[N],even[N],minn[N];
int tot=1,head[N],nxt[N<<1],ver[N<<1];
bool vis[N];
bitset<N> bit;
struct Node{int a,b,c;}s[N];
void add_edge(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs(int x)
{
dep[x]=dep[fa[x]]+1;
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(to==fa[x]) continue;
if(!dep[to])
{
fa[to]=x,dfs(to),odd[x]+=odd[to];
even[x]=min(even[x],even[to]),minn[x]=min(minn[x],minn[to]);
}
else if((dep[x]-dep[to])&1)
{
if(dep[x]>dep[to])
even[x]=min(even[x],dep[to]);
}
else if(dep[to]<dep[x])
odd[x]++,odd[fa[to]]--,all++,minn[x]=min(minn[x],dep[to]);
}
}
void solve()
{
n=read(); m=read(); bit.reset(); flag=false;
for(int i=1;i<=m;i++) s[i].a=read(),s[i].b=read(),s[i].c=read();
bit[s[1].a]=bit[s[1].b]=bit[s[1].c]=true;
for(int i=2;i<=m;i++)
{
bitset<N> b; b.reset(); b[s[i].a]=b[s[i].b]=b[s[i].c]=true;
if(!(bit&b).count()) return printf("no\n"),void(); bit&=b;
}
for(int i=1;i<=n;i++) if(bit[i]){pos=i;break;}
for(int i=1;i<=n&&!flag;i++)
{
tot=1; all=0;
for(int j=1;j<=n;j++) head[j]=odd[j]=dep[j]=fa[j]=0,even[j]=minn[j]=INF;
for(int j=1;j<=m;j++)
{
int a=s[j].a,b=s[j].b,c=s[j].c;
if(a==pos&&b!=i&&c!=i) add_edge(b,c),add_edge(c,b);
else if(b==pos&&a!=i&&c!=i) add_edge(a,c),add_edge(c,a);
else if(c==pos&&a!=i&&b!=i) add_edge(a,b),add_edge(b,a);
}
for(int j=1;j<=n;j++) if(j!=i&&j!=pos&&!dep[j]) dfs(j);
for(int j=1;j<=n&&!flag;j++)
if(odd[j]==all)
{
jud=true;
for(int k=head[j];k&&jud;k=nxt[k])
{
int to=ver[k];
if(dep[to]>dep[j]&&even[to]<dep[j]&&minn[to]<dep[j]) jud=false;
}
flag|=jud;
}
}
if(flag) printf("yes\n"); else printf("no\n");
}
signed main()
{
freopen("river.in","r",stdin); freopen("river.out","w",stdout);
T=read(); while(T--) solve(); return 0;
}
NOIP模拟64的更多相关文章
- 2021.9.28考试总结[NOIP模拟64]
T1 三元组 发现确定\(b,c\)的情况下,\(a\)的值域是连续的.确定\(b\)后\(a+b\)的取值是\([1+b,b+b]\).树状数组维护对每个\(b\)可行的\(c\). 注意取模后取值 ...
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- NOIP 模拟4 T2
本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...
- noip模拟23[联·赛·题]
\(noip模拟23\;solutions\) 怎么说呢??这个考试考得是非常的惨烈,一共拿了70分,为啥呢 因为我第一题和第三题爆零了,然后第二题拿到了70分,还是贪心的分数 第一题和第二题我调了好 ...
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
随机推荐
- 重学c#系列——缓存[盛派源码分析cache](九)
前言 以前整理过缓存的东西在: https://www.cnblogs.com/aoximin/p/12727659.html 只是粗略的例子,因为真的要去介绍缓存这个东西,要从内存开始,是一个有时间 ...
- c# unsafe
前言 c# unsafe可以让我们做一些测试的危险操作. 正文 打开unsafe 功能 在 Visual Studio 开发环境中设置此编译器选项 打开项目的"属性"页. 单击&q ...
- pytest-fixture使用
fixture(scope='function',params=None,autouse=False,ids=None,name=None):scope:设置作用域:params:传参数,以列表进行存 ...
- Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】
引言 上一章我们介绍了在xUnit单元测试中用xUnit.DependencyInject来使用依赖注入,上一章我们的Sample.Repository仓储层有一个批量注入的接口没有做单元测试,今天用 ...
- vscode使用ES6装饰器器语法
1. react项目 配置 package.json 需要安装 npm i @babel/plugin-proposal-decorators 可能需要重启项目 { "babel" ...
- HarmonyOS NEXT应用开发实战—组件堆叠
介绍 本示例介绍运用Stack组件以构建多层次堆叠的视觉效果.通过绑定Scroll组件的onScroll滚动事件回调函数,精准捕获滚动动作的发生.当滚动时,实时地调节组件的透明度.高度等属性,从而成功 ...
- 从原理到操作,让你在 Apache APISIX 中代理 Dubbo3 服务更便捷
简介: 本文为大家介绍了如何借助 Apache APISIX 实现 Dubbo Service 的代理,通过引入 dubbo-proxy 插件便可为 Dubbo 框架的后端系统构建更简单更高效的流量链 ...
- 解决 System.Net.Sockets.SocketException 10106 无法加载或初始化请求的服务提供程序 无法联网
本文收集 System.Net.Sockets.SocketException 异常错误码为 10106 导致无法联网的问题 这里的 10106 是 Win32 的 Socket 错误码,可以从 Wi ...
- Raft 共识算法2-领导者选举
Raft 共识算法2-领导者选举 Raft算法中译版地址:https://object.redisant.com/doc/raft中译版-2023年4月23日.pdf 英原论文地址:https://r ...
- 【Buildroot】使用记录
一.概述 之前只使用过 busybox,每次配置完 roots 文件时,只具备一些基础的工具,像移植 QT 之类的就显得很麻烦.直到现在接触到了 Buildroot,才发现配置工具可以这么简单,对于自 ...