T1 谜之阶乘

解题思路

二分答案,发现 \(a-b\) 至多为 19,毕竟 \(20!\) 已经大于 \(10^{18}\) 了。

对于每一种可能的差值,每一次二分 \(b+1\) 直接枚举乘积进行 check。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<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;
}
int T,n,fac[20];
inline int work(int x,int cnt)
{
__int128 temp=1;
for(int i=1;i<=cnt;i++)
{
temp*=x+i-1;
if(temp>n) return 1;
}
if(temp==n) return 0;return -1;
}
void solve()
{
n=read(); if(n==1) return printf("-1\n"),void();
vector<pair<int,int> > ans;
for(int cnt=1;cnt<=19&&fac[cnt]<=n;cnt++)
{
int l=2,r=n-cnt+1,temp=-1;
while(l<=r)
{
int mid=(l+r)>>1,t=work(mid,cnt);
if(!t){temp=mid;break;}
if(t==-1) l=mid+1; else r=mid-1;
}
if(~temp) ans.push_back(make_pair(temp+cnt-1,temp-1));
}
sort(ans.begin(),ans.end()); printf("%lld\n",(int)ans.size());
for(auto it :ans) printf("%lld %lld\n",it.first,it.second);
}
#undef int
int main()
{
#define int long long
freopen("factorial.in","r",stdin); freopen("factorial.out","w",stdout);
T=read(); fac[0]=1;
for(int i=1;i<=19;i++) fac[i]=fac[i-1]*i;
while(T--) solve();
return 0;
}

T2 子集

解题思路

假设每个集合的大小是 \(cnt\) 那么对于 \(cnt\) 是偶数的情况是可以直接对于奇偶按照不同的顺序来填就行。

那么对于 \(n\) 是偶数但是 \(cnt\) 是奇数的情况可以证明是不可行的。

然后对于 \(k,cnt\) 都是奇数的情况发现每个集合的前三个如果可以成功的排布,那么剩下的按照偶数的情况处理就好了。

对于第一列直接 \(1,2,3...n\) 顺序排布就好了,第二列先向 \(\frac{k+1}{2}+1\sim k\) 这一段区间从大到小填,然后再从大到小填 \(1\sim\frac{k+1}{2}\) 这一段区间就好了。

对于剩下的一列直接根据前两列的情况补上就好了。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
#define count __builtin_popcountll
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=1e6+10;
int T,n,m,cnt;
vector<int> ans[N];
void work1(int bas,int all)
{
for(int i=1;i<=all;i++)
if(i&1) for(int j=1;j<=m;j++) ans[j].push_back(++bas);
else for(int j=m;j>=1;j--) ans[j].push_back(++bas);
}
void work2(int bas=0)
{
for(int i=1;i<=m;i++) ans[i].push_back(++bas);
for(int i=m/2+2;i<=m;i++) ans[i].push_back(++bas);
for(int i=1;i<=m/2+1;i++) ans[i].push_back(++bas);
for(int i=1;i<=m;i++) ans[i].push_back(3*(3*m+1)/2-ans[i][0]-ans[i][1]);
}
void solve()
{
n=read(); m=read(); cnt=n/m;
if(m==1){printf("Yes\n");for(int i=1;i<=n;i++)printf("%lld ",i);putchar('\n');return ;}
if(n%2==0&&cnt%2) return printf("No\n"),void();
if(cnt%2&&cnt<3) return printf("No\n"),void();
for(int i=1;i<=m;i++) vector<int>().swap(ans[i]); printf("Yes\n");
if(cnt%2==0) work1(0,cnt);
else work2(),work1(3*m,cnt-3);
for(int i=1;i<=m;i++)
{
for(auto it:ans[i]) printf("%lld ",it);
putchar('\n');
}
}
#undef int
int main()
{
#define int long long
freopen("subset.in","r",stdin); freopen("subset.out","w",stdout);
T=read(); while(T--) solve();
return 0;
}

T3 混凝土粉末

解题思路

询问本质是:作若干次区间加,并询问 \(x\) 位置上的值最早 \(\ge y\) 的时间。

于是我们可以选择主席树,然后暴力二分+主席树可以达到 \(O(qlog^2n)\) 的复杂度,然后就会被卡常。

考虑一种离线做法,我们对于每一次插入操作 \((l,r,h)\) 分别在 \(l,r+1\) 两个地方记录下一个二元组 \((id,h)\) 。

然后扫描线扫 \(1\sim n\) 这个序列,用建立在操作标号上对于高度进行维护的树状数组或者线段树来处理答案。

这样我们就有了对于每一个下标而言所有有影响的操作的相对时间关系以及对应高度。

每次二分查找一个答案下标 \(mid\) 用树状数组查找 \(mid\) 操作以及以前操作所达到的高度 check。

这就是二分树状数组,由于常数优秀因此可以卡过,线段树或者树状数组二分也是类似的思路。

code

超大常数主席树

#include<bits/stdc++.h>
#define ll long long
#define ls tre[x].l
#define rs tre[x].r
using namespace std;
inline ll read()
{
ll 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=1e6+10;
int n,q,all,rt,root[N],id[N]; ll cnt;
struct Segment_Tree
{
struct Node{int l,r;ll dat;}tre[N*35];
inline int insert(register int pre,register int l,register int r,register int L,register int R,register int val)
{
register int x=++all,mid=(l+r)>>1; tre[x]=tre[pre];
if(L<=l&&r<=R) return tre[x].dat+=val,x;
if(L<=mid) ls=insert(tre[pre].l,l,mid,L,R,val);
if(R>mid) rs=insert(tre[pre].r,mid+1,r,L,R,val);
return x;
}
inline void query(register int x,register int l,register int r,register int pos)
{
if(!x||l==r) return cnt+=tre[x].dat,void(); register int mid=(l+r)>>1;
if(pos<=mid) return cnt+=tre[x].dat,query(ls,l,mid,pos),void();
return cnt+=tre[x].dat,query(rs,mid+1,r,pos),void();
}
}T;
int main()
{
freopen("concrete.in","r",stdin); freopen("concrete.out","w",stdout);
n=read(); q=read();
for(register int i=1,opt,x,z;i<=q;i++)
{
ll y; opt=read(); x=read(); y=read(); cnt=0;
if(opt==1){z=read();id[++rt]=i;root[rt]=T.insert(root[rt-1],1,n,x,y,z);continue;}
T.query(root[rt],1,n,x); if(cnt<y){printf("0\n");continue;}
register int l=0,r=rt,ans=0;
while(l<=r)
{
register int mid=(l+r)>>1; cnt=0; T.query(root[mid],1,n,x);
if(cnt>=y) ans=id[mid],r=mid-1; else l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}

二分树状数组

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<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=1e6+10;
int n,q,cnt,ans[N];
vector< pair<int,int> > v[N],ask[N];
struct BIT
{
int lim,tre[N];
#define lowbit(x) (x&(-x))
inline void insert(int x,int val){for(int i=x;i<=lim;i+=lowbit(i))tre[i]+=val;}
inline int query(int x){int sum=0;for(int i=x;i;i-=lowbit(i))sum+=tre[i];return sum;}
}T;
#undef int
int main()
{
#define int long long
freopen("concrete.in","r",stdin); freopen("concrete.out","w",stdout);
n=read(); q=read(); T.lim=q; memset(ans,-1,sizeof(ans));
for(int i=1,opt,x,y,z;i<=q;i++)
{
opt=read(); x=read(); y=read();
if(opt==2){ask[x].push_back(make_pair(i,y));continue;}
z=read(); v[x].push_back(make_pair(i,z));
v[y+1].push_back(make_pair(i,-z));
}
for(int i=1;i<=n;i++)
{
for(auto it:v[i]) T.insert(it.first,it.second);
for(auto it:ask[i])
{
int l=1,r=it.first; ans[it.first]=0;
while(l<=r)
{
int mid=(l+r)>>1,temp=T.query(mid);
if(temp>=it.second) ans[it.first]=mid,r=mid-1;
else l=mid+1;
}
}
}
for(int i=1;i<=q;i++) if(~ans[i]) printf("%lld\n",ans[i]);
return 0;
}

T4 排水系统

解题思路

考虑边 \((x,y)\) 堵塞所造成的影响。

其实就是对于 \(x\) 的其他出点的贡献增加了,而对于 \(y\) 的减少了。

相当于我们可以对于 \(x\) 点加上贡献然后在 \(y\) 点减去就好了。

具体实现就是先忽略所有老化的情况,算出每个点应该有污水,然后依次为基础算出每个点的初始期望污水。

最后在跑一遍就好了。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<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=2e5+10,M=5e5+10,mod=998244353;
int n,m,base,sta[N],r,ed,cnt[N],du[N],f[N],g[N];
int tot,head[N],ver[M],nxt[M],edge[M],fro[M];
void add(int &x,int y){x+=y;if(x>=mod)x-=mod;}
void add_edge(int x,int y,int val)
{
ver[++tot]=y; edge[tot]=val;
fro[tot]=x; du[y]++; cnt[x]++;
nxt[tot]=head[x]; head[x]=tot;
}
int power(int x,int y,int p=mod)
{
int temp=1;
for(;y;y>>=1,x=x*x%p)
if(y&1) temp=temp*x%p;
return temp;
}
#undef int
int main()
{
#define int long long
freopen("water.in","r",stdin); freopen("water.out","w",stdout);
n=read(); m=read(); r=read(); ed=read();
for(int i=1,x,y,val;i<=ed;i++)
{
x=read(); y=read(); val=read();
add_edge(x,y,val); add(base,val);
}
int top=0,pos=0; base=power(base,mod-2);
for(int i=1;i<=m;i++) sta[++top]=i;
while(top<n)
{
int x=sta[++pos];
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i]; du[to]--;
if(!du[to]) sta[++top]=to;
}
}
for(int i=1;i<=m;i++) f[i]=1;
for(int i=1;i<=n;i++)
{
int x=sta[i],temp=power(cnt[x],mod-2)*f[x]%mod;
for(int j=head[x];j;j=nxt[j]) add(f[ver[j]],temp);
}
for(int i=1;i<=n;i++)
{
if(!cnt[i]) continue;
int temp=f[i]*power(cnt[i]-1,mod-2)%mod;
for(int j=head[i];j;j=nxt[j])
{
add(g[i],temp*edge[j]%mod*base%mod);
add(g[ver[j]],(mod-temp%mod)*edge[j]%mod*base%mod);
}
}
for(int i=1;i<=m;i++) add(g[i],1);
for(int i=1;i<=n;i++)
{
int x=sta[i],temp=power(cnt[x],mod-2)*g[x]%mod;
for(int j=head[x];j;j=nxt[j]) add(g[ver[j]],temp);
}
for(int i=n-r+1;i<=n;i++) printf("%lld ",g[i]);
return 0;
}

NOIP模拟89(多校22)的更多相关文章

  1. NOIP模拟83(多校16)

    前言 CSP之后第一次模拟赛,感觉考的一般. 不得不吐槽多校联测 OJ 上的评测机是真的慢... T1 树上的数 解题思路 感觉自己思维有些固化了,一看题目就感觉是线段树. 考完之后才想起来这玩意直接 ...

  2. Noip模拟59 2021.9.22

    新机房首模拟变倒数 T1 柱状图 关于每一个点可以做出两条斜率分别为$1,-1$的直线, 然后题意转化为移动最少的步数使得所有点都在某一个点的两条直线上 二分出直线的高度,判断条件是尽量让这条直线上部 ...

  3. NOIP模拟赛-2018.10.22

    模拟赛 今天第一节课是历史,当然是不可能上的,一来到机房发现今天高二考试... 老师说以后可能还要给高一考...那还不如现在跟着做好了,毕竟在学长学姐中垫底显得没那么丢人 这套题风格挺奇怪的...为什 ...

  4. NOIP模拟92(多校25)

    前言 所以说这次是 HZOI 多校联测巅峰????(题目,数据过水??) T1 石子合并 解题思路 签到题. 发现我们可以给每个数字附一个正负号,每个数字的贡献就是它本身乘上这个符号. 发现至少应该有 ...

  5. NOIP模拟84(多校17)

    T1 宝藏 解题思路 考场上一眼出 \(nlog^2\) 做法,然后没看见是 1s 3e5 的数据,我竟然以为自己切了?? 考完之后尝试着把二分改为指针的移动,然后就过了??或许是数据水吧,感觉自己的 ...

  6. NOIP模拟85(多校18)

    前言 好像每个题目背景所描述的人都是某部番里的角色,热切好像都挺惨的(情感上的惨). 然后我只知道 T1 的莓,确实挺惨... T1 莓良心 解题思路 首先答案只与 \(w\) 的和有关系,于是问题就 ...

  7. NOIP模拟86(多校19)

    T1 特殊字符串 解题思路 \(f_{i,j}\) 表示前 \(i\) 个字符中结尾为 \(j\) 的最大贡献. 转移枚举当前位置于之前位置结尾的组合加上贡献即可. 对于边界问题,容易发现选择 1 一 ...

  8. NOIP模拟88(多校21)

    前言 对于这套题的总体感觉就是难,然后就是自己很菜... 对于 T1 考试时只会一个最垃圾的背包,考完之后对于思路这一块也不是很顺利,大概这就是薄弱的地方吧. 然后 T2 是比较简单的一道题了,但是考 ...

  9. NOIP模拟96(多校29)

    T1 子集和 解题思路 大概是一个退背包的大白板,然而我考场上想复杂了,竟然还用到了组合数. 但是大概意思是一样的,有数的最小值一定是一个在 \(a\) 数组中存在的数字. 那么我们想办法除去它对应的 ...

  10. NOIP模拟99(多校31)

    T1 法阵 解题思路 原题3100,张口放 T1(出题人原话) 思维题,合法的情况其实就是上下两个梯形拼起来的样子. 他们的边界都是在 \(i\) 轴上面,但是不能相交. 于是我们可以尝试两者相交的纵 ...

随机推荐

  1. js es6 map weakmap

    前言 这里介绍一些map和weakmap的一些属性和他们不同之处. 正文 map JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键.这 ...

  2. 【Oracle】PL/SQL制作唯一标识,固定字段+日期+流水码,流水码每日重置

    [Oracle]PL/SQL制作唯一标识,固定字段+日期+流水码,流水码每日重置 首先创建序列 create sequence sequence_name minvalue 0 maxvalue 99 ...

  3. 剑指offer04(Java)二维数组中的查找(中等)

    题目: 在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序.请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有 ...

  4. 力扣554(java&python)-砖墙(中等)

    题目: 你的面前有一堵矩形的.由 n 行砖块组成的砖墙.这些砖块高度相同(也就是一个单位高)但是宽度不同.每一行砖块的宽度之和相等. 你现在要画一条 自顶向下 的.穿过 最少 砖块的垂线.如果你画的线 ...

  5. 力扣393(java)-UTF-8编码验证(中等)

    题目: 给定一个表示数据的整数数组 data ,返回它是否为有效的 UTF-8 编码. UTF-8 中的一个字符可能的长度为 1 到 4 字节,遵循以下的规则: 对于 1 字节 的字符,字节的第一位设 ...

  6. 说说关系型数据库与Serverless

    简介: 看到如今Serverless在云计算行业喷薄欲出的态势,像极了<星星之火,可以燎原>中的描述:虽然不能预测未来的发展和变化,但对于云计算来说这是个相对确定的方向.本文从产业界和学术 ...

  7. 网易:Flink + Iceberg 数据湖探索与实践

    导读:今天主要和大家交流的是网易在数据湖 Iceberg 的一些思考与实践.从网易在数据仓库建设中遇到的痛点出发,介绍对数据湖 Iceberg 的探索以及实践之路. 主要内容包括: 数据仓库平台建设的 ...

  8. 更便捷:阿里云DCDN离线日志转存全新升级

    简介: 1月6日,阿里云CDN年度产品升级发布会中,阿里云CDN产品专家邓建伟宣布DCDN离线日志转存全新升级,并对离线日志转存方案的价值.应用及使用进行了详细解读. 在日常CDN加速服务过程中会产生 ...

  9. 无缝融入 Kubernetes 生态 | 云原生网关支持 Ingress 资源

    ​简介:Kubernetes 一贯的作风是通过定义标准来解决同一类问题,在解决集群对外流量管理的问题也不例外.Kubernetes 对集群入口点进行了进一步的统一抽象,提出了 3 种解决方案:Node ...

  10. [FE] yarn, npm 切换镜像源

    yarn 设置命令如下,会修改 ~/.yarnrc 内容. $ yarn config set registry https://registry.yarnpkg.com npm 设置命令如下,会修改 ...