Akane-Weekly #2NOIP 十连测 (2)
Akane-Weekly #2:NOIP 十连测 (2)
今日得分:40+35+0+80=155,完全寄了
C.
神仙题。
简要题意:
给你一个正整数 \(x\) 和一个质数 \(p\) ,让你找三个正整数 \(a,b,c\) ,满足 \(ab+bc+ca=xp^2\) ,或者报告无解。
Solution:
首先,我们可以将 \(ab+bc+ca\) 转化为 \((a+b)(a+c)-a^2\) 。
所以我们有 \((a+b)(a+c)=xp^2+a^2\) 。
很直接想到试一下 \(a=p\) ,发现可以凑出 \(a=p,b=x+1-p,c=p^2-p\) 。
发现只有当 \(x+1-p>0\) 是可以成立,固这一类子问题已经解决。
当 \(p>x+1\) 的时候,我们可以类似地解决,令 \(p=k+(x+1)b(0<k\le x)\) 。
我们让 \(a=k\) ,代入推一下式子,可以得到 \(b=x+1-k\) 和
发现 \(b,c\) 显然大于 \(0\) ,只需要满足 \(a>0\) 即可。
当 \(a=0\) 时,发现 \(b=1\) ,不然 \(p\) 就不是质数了。
所以我们最后需要考虑一下 \(x=k+1\) 的情况。
我们化简式子得到
待定系数,令 \(p^3+p^2+a^2=(p^2+yp+z)(p+u)\) 。
考虑到 \(zu\) 是完全平方数, \(z+yu=0\) 可以得到 \(-y\) 是完全平方数,枚举一下发现当 \(y=-4,u=3,z=12\) 时可以,所以有 \(a=6,b=p-3,c=p^2-4p+6\) 。
当然 \(p<=3\) 时不适用,手玩一下 \(x=1,p=2\) 和 \(x=2,p=3\) 的情况,发现均无解。
Code:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
signed main(){
// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t,x,p,a,b,c,k,by;
t=read();
while(t--){
x=read(),p=read();
if(x+1==p){
a=6,b=p-3,c=p*p-4*p+6;
}else{
a=k=p%(x+1);
by=p/(x+1);
b=x+1-a;
c=k*k+by*x*((x+1)*by+2*k)-a;
}
if((x==2&&p==3)||(x==1&&p==2)) printf("-1\n");
else printf("%lld %lld %lld\n",a,b,c);
}
}
B.
简要题意:
对于每一个个体,有一下五种操作:
1.向前走一步。
2.向后走一步,如果有标记且向后走之后位置小于标记,那么删除标记。
3.在当前位置打一个标记,一个个体只保留位置最小的标记。
4.走到标记处并清空标记,如果没有标记则不动。
5.询问这个个体的位置。
现在有 \(n\) 个个体,同时把操作 \(1-4\) 改成区间操作。
每个个体的初始位置均为 \(5e5\) ,且保证操作种类随机。
\(n,q\le5e5\) 。
Solution:
显然要用线段树维护,但问题在于怎么写。
考虑随机性,我们可以用二进制暴力维护每个个体每一位是否有标记的状态,如果要清空标记就清空数组重新开始,如果要后退就缩掉最后一位,搞一个 \(long long\) 数组维护,叫作 \(abj\) 。
维护每个个体的位置数字 \(a\) ,但它不用上推,只有当上面有要对 \(a\) 修改的时候进行下推即可。
维护一个 \(bool\) 数组 \(flg\) ,表示区间是否有个体打上了标记,方便在操作 \(4\) 线段树上下推的时候判断终止,这个要 \(pushup\) 维护。
还有两个数组 \(fgl,fgr\) ,前者记录 \(abj\) 的位数,即已经往前走未回溯的步数,方便回退的时候减掉,如果要减的比 \(fgl\) 多,就记在 \(fgr\) 里面,当做懒标记下推即可。
操作 \(4\) 的时候即使找到了包含区间也要继续推来清除 \(flg\) ,不过由于随机性,时间也可以保证,(能过就可以了
~)
Code:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,q;
bool flg[2000010];//表示标记(原题中的)为不为空。
int fgl[2000010],fgr[2000010],a[2000010];
long long abj[2000010];//每一个梦境增加标记状态,状压,由于随机性,可以得到大概率不会超过64个未清除的标记,所以可以这样操作。(关键)
struct tree{
int l,r;
}t[2000010];
void pu(int id){
flg[id]=abj[id]|flg[id<<1]|flg[id<<1|1];
}
void get_abj(int id,int k){
abj[id]|=k,flg[id]=1;
}
void get_new(int id,int k){
abj[id]<<=k,fgl[id]+=k;
}
void get_a(int id,int k){
a[id]+=k;
}
void get_d(int id,int k){
if(k<64) abj[id]>>=k;
else abj[id]=0;
if(k<fgl[id]) fgl[id]-=k;
else fgr[id]+=k-fgl[id],fgl[id]=0;
}
void pd(int id){
if(a[id]) a[id<<1]+=a[id],a[id<<1|1]+=a[id],a[id]=0;
if(fgr[id]) get_d(id<<1,fgr[id]),get_d(id<<1|1,fgr[id]),fgr[id]=0;
if(fgl[id]) get_new(id<<1,fgl[id]),get_new(id<<1|1,fgl[id]),fgl[id]=0;
if(abj[id]) get_abj(id<<1,abj[id]),get_abj(id<<1|1,abj[id]),abj[id]=0;
}
void build(int id,int l,int r){
t[id].l=l,t[id].r=r;
if(l==r){
a[id]=500000;
return;
}
int mid=(l+r)>>1;
build(id<<1,l,mid),build(id<<1|1,mid+1,r);
}
int query(int id,int x){
if(t[id].l==t[id].r){
return a[id];
}
pd(id);
int mid=(t[id].l+t[id].r)>>1;
if(x<=mid) return query(id<<1,x);
else return query(id<<1|1,x);
}
void update3(int id,int l,int r){
if(l<=t[id].l&&t[id].r<=r){
get_abj(id,1);
return;
}
pd(id);
int mid=(t[id].l+t[id].r)>>1;
if(l<=mid) update3(id<<1,l,r);
if(r>mid) update3(id<<1|1,l,r);
pu(id);
}
void update1(int id,int l,int r){
if(l<=t[id].l&&t[id].r<=r){
get_a(id,1),get_new(id,1);
return;
}
pd(id);
int mid=(t[id].l+t[id].r)>>1;
if(l<=mid) update1(id<<1,l,r);
if(r>mid) update1(id<<1|1,l,r);
pu(id);
}
void update2(int id,int l,int r){
if(l<=t[id].l&&t[id].r<=r){
get_a(id,-1),get_d(id,1);
return;
}
pd(id);
int mid=(t[id].l+t[id].r)>>1;
if(l<=mid) update2(id<<1,l,r);
if(r>mid) update2(id<<1|1,l,r);
pu(id);
}
void update4(int id,int l,int r){
if(l<=t[id].l&&t[id].r<=r){
if(t[id].l==t[id].r||(flg[id<<1]==0&&flg[id<<1|1]==0)){
a[id]-=(abj[id]==0?0:63-__builtin_clzll(abj[id]));
}else{
pd(id),update4(id<<1,l,r),update4(id<<1|1,l,r);
}
abj[id]=fgl[id]=fgr[id]=flg[id]=0;
return;
}
pd(id);
int mid=(t[id].l+t[id].r)>>1;
if(l<=mid) update4(id<<1,l,r);
if(r>mid) update4(id<<1|1,l,r);
pu(id);
}
int main(){
n=read(),q=read();
build(1,1,n);
while(q--){
int op,l,r;
op=read(),l=read(),r=read();
if(op==1) update1(1,l,r);
if(op==2) update2(1,l,r);
if(op==3) update3(1,l,r);
if(op==4) update4(1,l,r);
if(op==5) printf("%d\n",query(1,l));
}
return 0;
}

浙公网安备 33010602011771号