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的更多相关文章

  1. 2021.9.28考试总结[NOIP模拟64]

    T1 三元组 发现确定\(b,c\)的情况下,\(a\)的值域是连续的.确定\(b\)后\(a+b\)的取值是\([1+b,b+b]\).树状数组维护对每个\(b\)可行的\(c\). 注意取模后取值 ...

  2. NOIP模拟题汇总(加厚版)

    \(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...

  3. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  4. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  5. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  6. noip模拟23[联·赛·题]

    \(noip模拟23\;solutions\) 怎么说呢??这个考试考得是非常的惨烈,一共拿了70分,为啥呢 因为我第一题和第三题爆零了,然后第二题拿到了70分,还是贪心的分数 第一题和第二题我调了好 ...

  7. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  8. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  9. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  10. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

随机推荐

  1. mysql 必知必会整理—sql 简单语句[二]

    前言 简单整理一下sql 排序与过滤. 正文 在这里需要创建一下一个数据库实例. 为了方便直接用docker 创建一下啊,方便简洁. https://hub.docker.com/_/mysql 按照 ...

  2. sass 基本常识

    一.什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. 本文总结了SASS的主要用法.我的目标是,有了这篇文章,日常的一 ...

  3. arp 的概念解析

    前言 这里基于arp的基础概念,请先看前面那一节. 正文 看图: 和前面一样去解析地址. 以太网目的地址:就是mac地址. 在发送arp包的时候呢,这个mac地址就是全部是1,因为不知道对方地址是啥. ...

  4. xilinx的serdes接收时钟坑

    ilinx的7 series fpga transceivers wizard用于自定义的serdes编码. 要选择多个serdes端口,如下图,点击对应的名称,然后右边选择use该设备就可以. 生成 ...

  5. 力扣485(java)-最大连续数1的个数(简单)

    题目: 给定一个二进制数组, 计算其中最大连续 1 的个数. 示例: 输入:[1,1,0,1,1,1]输出:3解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3. 提示: 输入 ...

  6. Android Native crash 处理案例分享

    简介: Android Native crash 处理案例分享 1. 背景 目前 mPaas[1] Android使用Crash SDK对闪退进行的处理,CrashSDK 是 Android 平台上一 ...

  7. 重磅发布 阿里云数据中台全新产品DataTrust聚焦企业数据安全保障

    简介: DataTrust(隐私增强计算产品)是基于阿里云底层多项基础安全能力,经过阿里云数据中台丰富的客户业务实践,构建的一款为企业数据安全流通的产品. 随着包括零售.制造.金融等多行业数字化转型加 ...

  8. Region-区域(默认和新增)适配器

    Prism内置了几个区域适配器 ContentControlRegionAdapter ItemsControlRegionAdapter SelectorRegionAdapter ComboBox ...

  9. 国内常用源开发环境换源(flutter换源,python换源,Linux换源,npm换源)

    国内开源镜像站点 大学 清华大学开源软件镜像站 (使用较多) 中国科学技术大学开源软件镜像 (使用较多) 浙江大学开源镜像站 (主要是各发行版Linux,pip等常用库) 哈尔滨工业大学开源镜像站 ( ...

  10. vue-router设置页面切换滑动效果的方法及解决遇到的坑

    先上gif:这里演示顺序是1232121 1.router.js中配置入口路由 {     path: '/',     redirect: '/index'   } 2.main.js中new vu ...