CSP-S模拟4
下发文件和题解
A. 石子游戏
懒得写了,搬的官方题解
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 500001
#define pll pair<ll,ll>
#define put_ putchar(' ')
#define putn putchar('\n')
#define Alice putchar('A'),putchar('l'),putchar('i'),putchar('c'),putchar('e')
#define Bob putchar('B'),putchar('o'),putchar('b')
using namespace std;
static inline ll read()
{
rll f=0,x=0;rg char ch=getchar();
while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return f?-x:x;
}
static inline void write(rll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);putchar(x%10|'0');
}
ll n,mx,ans;
ll a[maxn],tot[maxn],sum[maxn],dp[maxn][20];
bool fl;
int main()
{
n=read();mx=log2(n)+1;
for(rll i=1;i<=n;i++) a[i]=read(),tot[a[i]]++;
for(rll i=1;i<=n;i++) sum[i]=sum[i-1]+tot[i];
for(rll i=n;i+1;i--)
for(rll j=0;j<=mx;j++)
dp[i][j]=dp[min(n,i+(1<<j+1)-1)+1][j]+sum[min(n,i+(1<<j+1)-1)]-sum[i+(1<<j)-1];
for(rll i=1;i<=n;i++)
{
for(rll j=0,t;j<=mx;j++)
{
fl=ans=0;t=n/(i+1);
for(rll k=0;k<=t;k++)
{
rll l=(i+1)*k,r=min(n,(i+1)*(k+1)-1),p=r-l+1>>j+1;
ans+=dp[l][j]-dp[l+p*(1<<j+1)][j];
if(l+p*(1<<j+1)+(1<<j)-1<r) ans+=sum[r]-sum[l+p*(1<<j+1)+(1<<j)-1];
}
if(ans&1) { Alice; put_; fl=1; break; }
}
if(!fl) Bob,put_;
}
return 0;
}
B. 大鱼吃小鱼
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 300001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
static inline ll read()
{
rll f=0,x=0;rg char ch=getchar();
while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return f?-x:x;
}
static inline void write(rll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);putchar(x%10|'0');
}
struct node
{
#define ls(x) t[x].ls
#define rs(x) t[x].rs
ll sum,mn,v,ls,rs,siz,rnd;
}t[maxn<<1];
ll n,q,s,k,w,rt,cnt;
ll a[maxn];
bool fl;
stack<ll> sta;
static inline ll New(rll x)
{
t[cnt].v=t[cnt].sum=t[++cnt].mn=x;
t[cnt].rnd=rand();t[cnt].siz=1;return cnt;
}
static inline void pushup(rll rt)
{
t[rt].siz=t[ls(rt)].siz+t[rs(rt)].siz+1;
t[rt].sum=t[ls(rt)].sum+t[rs(rt)].sum+t[rt].v;
if(ls(rt)) t[rt].mn=t[ls(rt)].mn;else t[rt].mn=t[rt].v;
}
static inline void build(rll& rt,rll l,rll r)
{
rll mid=(l+r)>>1;rt=New(a[mid]);
if(l<mid) build(ls(rt),l,mid-1);if(r>mid) build(rs(rt),mid+1,r);
pushup(rt);
}
static inline ll merge(rll x,rll y)
{
if(!x||!y) return x|y;
if(t[x].rnd<t[y].rnd) { rs(x)=merge(rs(x),y); pushup(x); return x; }
ls(y)=merge(x,ls(y)); pushup(y); return y;
}
static inline void updsiz(rll rt,rll k,rll& x,rll& y)
{
if(!rt) { x=y=0; return; }
if(k>t[ls(rt)].siz) x=rt,updsiz(rs(rt),k-t[ls(rt)].siz-1,rs(rt),y);
else y=rt,updsiz(ls(rt),k,x,ls(rt));
pushup(rt);
}
static inline void updval(rll rt,rll k,rll& x,rll& y)
{
if(!rt) { x=y=0; return; }
if(k<t[rt].v) y=rt,updval(ls(rt),k,x,ls(rt));
else x=rt,updval(rs(rt),k,rs(rt),y);
pushup(rt);
}
static inline void split(rll rt,rll k,rll& x,rll& y)
{
if(!rt) { x=y=0; return; }
if(k>t[rs(rt)].sum) y=rt,split(ls(rt),k-t[rs(rt)].sum-t[rt].v,x,ls(rt));
else x=rt,split(rs(rt),k,rs(rt),y);
pushup(rt);
}
static inline void re_build(rll x,rll y)
{
rt=merge(x,y);
while(!sta.empty())
{
rll k=sta.top();sta.pop();
updval(rt,t[k].v,x,y);rt=merge(merge(x,k),y);
}
}
int main()
{
srand(time(0));n=read();for(rll i=1;i<=n;i++) a[i]=read();
sort(a+1,a+n+1);build(rt,1,n);q=read();
while(q--)
{
rll a,b,x=0,y=rt,ans=0,p=read();fl=0;
switch(p)
{
case 1:
s=read();k=read();
while(s<k)
{
updval(y,s-1,a,y);x=merge(x,a);
if(y) b=min(t[y].mn+1,k);else b=k;
if(s+t[x].sum<b) { puts("-1"); re_build(x,y); fl=1; break; }
split(x,b-s,x,a);sta.push(a);
ans+=t[a].siz;s+=t[a].sum;
}
if(!fl) write(ans),putn,re_build(x,y);
break;
case 2:
w=read();
updval(rt,w,a,b);rt=merge(merge(a,New(w)),b);
break;
case 3:
w=read();updval(rt,w,a,b);
updsiz(a,t[a].siz-1,a,x);rt=merge(a,b);
break;
}
}
return 0;
}
C. 黑客
签到题,因为合法的和只有1-999,枚举x与y,直接计算在询问范围内的倍数数量.
(我赛时想的莫反,结果越推越乱)
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 300001
#define mod 1000000007
#define put_ putchar(' ')
#define putn putchar('\a')
using namespace std;
static inline ll read()
{
rll f=0,x=0;rg char ch=getchar();
while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return f?-x:x;
}
static inline void write(rll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);putchar(x%10|'0');
}
ll a,b,c,d,e,f,g,h,i,j;
static inline ll gcd(rll x,rll y) { return !y?x:gcd(y,x%y); }
static inline ll jiaoji(rll a,rll b,rll c,rll d)
{
rll ans=0;
for(rll t=1;t<=999;t++)
for(rll k=1;k<=999-t;k++)
if(!(gcd(t,k)-1))
{
e=ceil((double)a/t);f=b/t;g=ceil((double)c/k);h=d/k;
i=max(e,g);j=min(f,h);
if(!(j-i&LLONG_MIN)/*j-i>=0*/) ans=(ans+(t+k)*(j-i+1)%mod)%mod;
}
return ans;
}
int main()
{
a=read();b=read();c=read();d=read();
write(jiaoji(a,b,c,d));
return 0;
}
D. 黑客-续
简单的数位dp,其实最难实现的就是高精度了,需要压位,而且要卡常才能过.
点击查看代码
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")// 我这里懒得卡常了,加了个优化
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 521
#define maxm 61
#define base 100000000000000000
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
static inline ll read()
{
rll f=0,x=0;rg char ch=getchar();
while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return f?-x:x;
}
static inline void write(rll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);putchar(x%10|'0');
}
struct bigint
{
ll a[maxm],len;
bigint() { memset(a,0,sizeof(a));len=1; }
bigint(rll x)
{
memset(a,0,sizeof(a));len=0;
// if(!x) len=1;
while(x) a[++len]=x%base,x/=base;
}
inline friend bigint operator+(rg bigint a,rg bigint b)
{
rg bigint c;rll i=1;
for(;i<=a.len||i<=b.len;i++)
{
c.a[i]+=a.a[i]+b.a[i];
c.a[i+1]+=c.a[i]/base;c.a[i]%=base;
}
if(!c.a[i]) i--;c.len=i;return c;
}
inline friend bigint operator*(rg bigint a,rll b)
{
rll x=0;
for(rll i=1;i<=a.len;i++) { rll y=a.a[i]*b+x;a.a[i]=y%base;x=y/base; }
while(x) a.a[++a.len]=x%base,x/=base;return a;
}
inline friend bigint operator*(rg bigint a,rg bigint b)
{
rg bigint c;
for(rll i=1;i<=a.len;i++)
for(rll j=1;j<=b.len;j++)
{
c.a[i+j-1]+=a.a[i]*b.a[j];
c.a[i+j]+=c.a[i+j-1]/base;c.a[i+j-1]%=base;
}
c.len=a.len+b.len;while(c.len>1&&(!c.a[c.len])) c.len--;return c;
}
inline friend bigint operator/(rg bigint a,rll b)
{
rll x=0;
for(rll i=a.len;i;i--) { x+=a.a[i];a.a[i]=x/b;x=x%b*base; }
while((!a.a[a.len])&&a.len>1) a.len--;return a;
}
inline friend void operator+=(rg bigint& a,rll b) { a=a+b; }
inline friend void operator+=(rg bigint& a,rg bigint b) { a=a+b; }
}cnt[2][maxn],sum[2][maxn],ans,ansp;
static inline void write(rg bigint a)
{
write(a.a[a.len]);
for(rll i=a.len-1;i;i--) printf("%017lld",a.a[i]);
}
static inline bigint pow(rg bigint a,rll b) { rg bigint c=a;for(rll i=1;i<b;i++) c=c*a; return c; }
ll n,m,k,mx;
ll a,b,c[maxn];
bitset<20> fl[maxn];
bool gd;
int main()
{
n=read();m=read();k=read();mx=(1<<k);
for(rll i=1;i<=m;i++) a=read(),b=read(),c[b]|=(1<<(a-1));
for(rll i=0;i<mx;i++) for(rll j=1;j<=k;j++) fl[i][j]=!(i&c[j]);
cnt[0][0]=1;
for(rll i=1;i<=n;i++)
{
gd^=1;
for(rll j=0;j<mx;j++)
{
for(rll l=1;l<=k;l++)
if(fl[j][l])
cnt[gd][j|(1<<l-1)]+=cnt[gd^1][j],
sum[gd][j|(1<<l-1)]+=sum[gd^1][j]*10+cnt[gd^1][j]*l;
sum[gd^1][j]=cnt[gd^1][j]=0;
}
}
for(rll i=0;i<mx;i++)
ans+=cnt[gd][i],ansp+=sum[gd][i];
write(ans);putn;write(ansp);
return 0;
}
--END--
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/p/16683419.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!