两次考试

11.6

T1

super_gcd

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}
const int LEN=1006;

int t[LEN],he;
int cm;

struct bign
{
int s[LEN],len;
bign(){mem(s,0);len=1;}
{
int i;
he=0; char q=getchar();
while(q<'0'||q>'9') q=getchar();
while(q>='0'&&q<='9') t[++he]=q-'0',q=getchar();
for(i=he;i;--i) s[he-i+1]=t[i];
len=he;
}
bool operator < (const bign &c) const
{
bign x=*this;
if(x.len==c.len)
{
int i;
for(i=x.len;i;--i)
{
if(x.s[i]==c.s[i]) continue;
return x.s[i]<c.s[i];
}
}
else
return x.len<c.len;
return 0;
}
bign operator - (const bign &c) const
{
bign x=*this; int i;
for(i=1;i<=c.len;++i)
{
x.s[i+cm]-=c.s[i];
if(x.s[i+cm]<0)
{
--x.s[i+cm+1];
x.s[i+cm]+=10;
}
}
while(x.len>1&&x.s[x.len]==0)
--x.len;
return x;
}
void out()
{
int i;
for(i=len;i;--i)
printf("%d",s[i]);
puts("");
}
};

int T;
bign A,B;

int gcd()
{
while( !(A.len==1&&A.s[1]==0)&&!(B.len==1&&B.s[1]==0) )
{
if(A<B)
{
cm=B.len-A.len-1;
if(cm<0) cm=0;
B=B-A;
}
else
{
cm=A.len-B.len-1;
if(cm<0) cm=0;
A=A-B;
}
}
//A.out(); B.out();
if(A<B)
{
if(B.len==1&&B.s[1]==1&&A.len==1&&A.s[1]==0)
return 1;
return 0;
}
else
{
if(A.len==1&&A.s[1]==1&&B.len==1&&B.s[1]==0)
return 1;
return 0;
}
}

int main(){

//freopen("T1.in","r",stdin);

//freopen("king.in","r",stdin);
//freopen("king.out","w",stdout);

while(T--)
{
//A.out(); B.out();
if(gcd())
puts("Yes");
else
puts("No");
}
}
T1

T2

$O(n)$

$$pre_r-pre_{l-1}>\frac{r-l+1}{2}$$

$$2*pre_r-r>2*pre_{l-1}-l+1$$

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
char q=getchar();
while(q<'0'||q>'9') q=getchar();
x=q-'0';
}
const int N=5000006;

int n;
int cm;
int aee=5000000;
int cnt[N<<1],v[N];
ll ans;

ll get()
{
rint i; int tt; ll ans=0,now=aee,ccc=0;
mem(cnt,0); ++cnt[aee];
for(i=1;i<=n;++i)
{
if(v[i]==cm) ccc+=cnt[now],++now;
else --now,ccc-=cnt[now];
++cnt[now];
ans+=ccc;
}
return ans;
}

int main(){

//freopen("ex1.in","r",stdin);

rint i;

scanf("%d",&n);

/*printf("\n");
for(i=1;i<=n;++i)
printf("%d",v[i]);
printf("\n");*/

ans=1LL*n*(n+1)/2;
for(i=0;i<3;++i)
cm=i,ans-=get();
printf("%lld\n",ans);
}
T2

T3

$O(n^3)$的dp很简单，但是我根本没想...

70分 还可以打网络流

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 0.00000001
#define dd double
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}
const int N=100006;
const ll Inf=1e10;

int n,A,B;
int now,pr;
dd p[N],q[N];
dd f[2];
int ga[2],gb[2];

void check(dd xp,dd xq)
{
rint i,j;
now=0;
f[0]=0; ga[0]=gb[0]=0;
for(i=1;i<=n;++i)
{
now^=1; pr=now^1;
f[now]=-Inf; ga[now]=gb[now]=0;
if(f[now]<f[pr])
f[now]=f[pr],ga[now]=ga[pr],gb[now]=gb[pr];
if(f[now]<f[pr]+p[i]-xp)
f[now]=f[pr]+p[i]-xp,ga[now]=ga[pr]+1,gb[now]=gb[pr];
if(f[now]<f[pr]+q[i]-xq)
f[now]=f[pr]+q[i]-xq,ga[now]=ga[pr],gb[now]=gb[pr]+1;
if(f[now]<f[pr]+p[i]+q[i]-p[i]*q[i]-xp-xq)
f[now]=f[pr]+p[i]+q[i]-p[i]*q[i]-xp-xq,ga[now]=ga[pr]+1,gb[now]=gb[pr]+1;
}
}

dd work()
{
dd l=0,r=1,mid,l2,r2,mid2;
while(l<r-eps)
{
mid=(l+r)/2.0;
//printf("l=%f r=%f mid=%f\n",l,r,mid);
l2=0; r2=1;
while(l2<r2-eps)
{
mid2=(l2+r2)/2.0;
//printf("l2=%f r2=%f mid2=%f gb[now]=%d\n",l2,r2,mid2,gb[now]);
check(mid,mid2);
if(gb[now]==B)
break;
if(gb[now]<B) r2=mid2;
else l2=mid2;
}
if(ga[now]==A)
break;
if(ga[now]<A) r=mid;
else l=mid;
}
return f[now]+mid*A+mid2*B;
}

int main(){

//freopen("in.in","r",stdin);

//freopen("red8.in","r",stdin);

rint i;

while(~scanf("%d%d%d",&n,&A,&B))
{
for(i=1;i<=n;++i) scanf("%lf",&p[i]);
for(i=1;i<=n;++i) scanf("%lf",&q[i]);
if(A>n) A=n;
if(B>n) B=n;
printf("%.3f\n",work());
}
}
T3

11.7

T1

T一定可以分解成$S*B^{a}+n1*A*B^{a-1}+n2*A*B^{a-2}...$的形式

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}

int S,T,A,B;
int maxk;
ll P[106];

int main(){

//freopen("T1.in","r",stdin);
//freopen("T1hh.out","w",stdout);

//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);

rint i,j; ll tt,t1; int con,ans=1e9;

if(S>T)
{
puts("-1");
return 0;
}

tt=S; maxk=0;
while(tt<=T&&maxk<=32) tt*=B,++maxk;
--maxk; tt/=B;

P[0]=1;
for(i=1;i<=maxk;++i)
P[i]=P[i-1]*B;

for(i=maxk;~i;--i)
{
tt=S*P[i]; con=i;
for(j=i;~j;--j)
{
t1=(1LL*T-tt)/(1LL*A*P[j]);
con+=t1; tt+=1LL*t1*A*P[j];
}
if(tt==T&&ans>con) ans=con;
}
if(ans==1000000000)
ans=-1;
printf("%d\n",ans);
}
T1

T2

$O(nlog^2n)$

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}
const int N=100006;

int n,m;
int u[N],v[N],len[N];

int check60(int maxd)
{
rint i,j; int mn,mx,t1,t2;
for(i=1;i<=n;++i)
{
mn=1000000; mx=1;
for(j=1;j<=m;++j)
if(len[j]>maxd)
{
t1=u[j]-i; if(t1<0) t1=-t1;
if(t1>maxd)
{
mn=1; mx=1000000;
break;
}
t2=maxd-t1;
if(mn>v[j]+t2) mn=v[j]+t2;
if(mx<v[j]-t2) mx=v[j]-t2;
}
if(mx<=mn) return 1;
}
return 0;
}

int work60()
{
int l=0,r=n,mid,ans=n;
while(l<=r)
{
mid=(l+r)>>1;
//printf("l=%d r=%d mid=%d\n",l,r,mid);
if(check60(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}

int check100(int maxd)
{
int l=0,r=maxd,mid;
int mn,mx,t1,t2,tt,l1=n,r1=1;
rint i,j;
while(l<=r)
{
mid=(l+r)>>1;
//printf("l2=%d r2=%d mid2=%d\n",l,r,mid);
mn=n; mx=1;
for(i=1;i<=m;++i)
if(len[i]>maxd)
{
if(mx<u[i]-mid) mx=u[i]-mid;
if(mn>u[i]+mid) mn=u[i]+mid;
}
//printf("mn=%d mx=%d\n",mn,mx);
if(mx>mn) l=mid+1;
else
{
l1=mx,r1=mn,r=mid-1;
/*if(l1>mx) l1=mx;
if(r1<mn) r1=mn;
r=mid-1;*/
/*if(r1-l1<mn-mx)
l1=mx,r1=mn;
r=mid-1;*/
}
}
if(l1>r1) return 0;
//printf("l1=%d r1=%d mid=%d\n",l1,r1,mid);
for(i=l1;i<=r1;++i)
{
t1=n; t2=1;
for(j=1;j<=m;++j)
if(len[j]>maxd)
{
tt=u[j]-i; if(tt<0) tt=-tt;
tt=maxd-tt;
if(t2<v[j]-tt) t2=v[j]-tt;
if(t1>v[j]+tt) t1=v[j]+tt;
}
//printf("asdsd:: %d %d\n",t2,t1);
if(t2<=t1) return 1;
}
return 0;
}

int work100()
{
int l=0,r=n,mid,ans=n;
while(l<=r)
{
mid=(l+r)>>1;
//printf("l=%d r=%d mid=%d\n",l,r,mid);
if(check100(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}

int main(){

//freopen("T2.in","r",stdin);
//freopen("T2.out","w",stdout);

//freopen("b.in","r",stdin);
//freopen("b.out","w",stdout);

rint i;

for(i=1;i<=m;++i)
if(n<=5000)
printf("%d\n",work60());
else
printf("%d\n",work100());
}
1

$O(nlog^2n)$

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}
const int N=100006;

int n,m;
int u[N],v[N],len[N];

int check2(int pos,int maxd)
{
rint i; int l1=1,r1=n,t1;
for(i=1;i<=m;++i)
if(len[i]>maxd)
{
t1=u[i]-pos; if(t1<0) t1=-t1;
if(t1>maxd) return 0;
}
for(i=1;i<=m;++i)
if(len[i]>maxd)
{
t1=u[i]-pos; if(t1<0) t1=-t1;
t1=maxd-t1;
if(l1<v[i]-t1) l1=v[i]-t1;
if(r1>v[i]+t1) r1=v[i]+t1;
}
if(l1<=r1) return 1;
return 0;
}

int check(int pos)
{
rint i;
int l=0,r=n,mid,ans=n;
while(l<=r)
{
mid=(l+r)>>1;
if(check2(pos,mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}

int work()
{
int l=1,r=n,mid,midmid,midv,midmidv,ans=n,i;
while(l<=r-10)
{
mid=l+(r-l)/3; midmid=r-(r-l)/3;
midv=check(mid); midmidv=check(midmid);
if(midv>midmidv)
{
if(ans>midmidv) ans=midmidv;
l=mid;
}
else
{
if(ans>midv) ans=midv;
r=midmid;
}
}
for(i=l;i<=r;++i)
{
midv=check(i);
if(ans>midv) ans=midv;
}
return ans;
}

int main(){

//freopen("T2.in","r",stdin);

rint i;

for(i=1;i<=m;++i)
printf("%d\n",work());
}
2

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}
const int N=100006;
const int Inf=1e9;

int n,m;
int u[N],v[N],len[N];

int check(int maxd)
{
rint i;
int l=-Inf,r=Inf,xi=-Inf,sh=Inf;
int t1,t2;
int sha,xia,zuo,you;
for(i=1;i<=m;++i)
if(len[i]>maxd)
{
sha=-Inf; xia=Inf; zuo=Inf; you=-Inf;
t1=u[i]-maxd+v[i]; t2=u[i]-maxd-v[i];
if(sha<t2) sha=t2; if(xia>t2) xia=t2;
if(you<t1) you=t1; if(zuo>t1) zuo=t1;
t1=u[i]+maxd+v[i]; t2=u[i]+maxd-v[i];
if(sha<t2) sha=t2; if(xia>t2) xia=t2;
if(you<t1) you=t1; if(zuo>t1) zuo=t1;
t1=u[i]+v[i]-maxd; t2=u[i]-(v[i]-maxd);
if(sha<t2) sha=t2; if(xia>t2) xia=t2;
if(you<t1) you=t1; if(zuo>t1) zuo=t1;
t1=u[i]+v[i]+maxd; t2=u[i]-(v[i]+maxd);
if(sha<t2) sha=t2; if(xia>t2) xia=t2;
if(you<t1) you=t1; if(zuo>t1) zuo=t1;

if(l<zuo) l=zuo; if(r>you) r=you;
if(xi<xia) xi=xia; if(sh>sha) sh=sha;
}
if(xi<=sh&&l<=r)
return 1;
return 0;
}

int work()
{
int l=0,r=n,mid,ans=n;
while(l<=r)
{
mid=(l+r)>>1;
//printf("l=%d r=%d mid=%d\n",l,r,mid);
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}

int main(){

//freopen("T2.in","r",stdin);
//freopen("T2.out","w",stdout);

rint i;

for(i=1;i<=m;++i)
printf("%d\n",work());
}
3

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}
const int Inf=1e9;
const int N=100006;

int n,m;
int u[N],v[N],len[N];

int check(int maxd)
{
rint i; int l=-Inf,r=Inf;
for(i=1;i<=m;++i)
if(len[i]>maxd)
{
if(l<u[i]+v[i]-maxd) l=u[i]+v[i]-maxd;
if(r>u[i]+v[i]+maxd) r=u[i]+v[i]+maxd;
}
//printf("l1=%d r1=%d\n",l,r);
if(l>r) return 0;
l=-Inf; r=Inf;
for(i=1;i<=m;++i)
if(len[i]>maxd)
{
if(l<u[i]-v[i]-maxd) l=u[i]-v[i]-maxd;
if(r>u[i]-v[i]+maxd) r=u[i]-v[i]+maxd;
}
//printf("l2=%d r2=%d\n",l,r);
if(l>r) return 0;
return 1;
}

int work()
{
int l=0,r=n,mid,ans=n;
while(l<=r)
{
mid=(l+r)>>1;
//printf("l=%d r=%d mid=%d\n",l,r,mid);
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}

int main(){

//    freopen("T2.in","r",stdin);

rint i;
for(i=1;i<=m;++i)
printf("%d\n",work());
}
4

T3

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
{
x=0; int ff=1; char q=getchar();
while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
x*=ff;
}
const int N=300006;
int first[N],nt[N<<1],ver[N<<1],e;
{
ver[e]=v;
nt[e]=first[u];
first[u]=e++;
}

int n,alln;
int v[N],t[N],pos[N];
int x[N<<1],y[N<<1];

int dfn[N],low[N],tim,zhan[N],he,sun[N],sum;
bool flag[N];
void tarjan(int x)
{
dfn[x]=low[x]=++tim;
zhan[++he]=x; flag[x]=1;
int i;
for(i=first[x];i!=-1;i=nt[i])
{
if(dfn[ver[i]]==-1)
{
tarjan(ver[i]);
if(low[x]>low[ver[i]])
low[x]=low[ver[i]];
}
else
if(flag[ver[i]]&&low[x]>dfn[ver[i]])
low[x]=dfn[ver[i]];
}
if(dfn[x]==low[x])
{
i=-1; ++sum;
while(i!=x)
i=zhan[he--],flag[i]=0,++sun[sum];
}
}

int check(int arr)
{
rint i; int tt;
for(i=0;i<n;++i) t[i]=v[i];
for(i=1;i<=arr;++i) swap(t[x[i]],t[y[i]]);

/*printf("\n");
for(i=0;i<n;++i)
printf("%d ",t[i]);
printf("\n");*/

for(i=0;i<n;++i) pos[t[i]]=i;
for(i=0;i<n;++i) sun[i]=0,dfn[i]=-1,first[i]=-1;
e=0; tim=0; he=0; sum=0;
for(i=0;i<n;++i)
if(dfn[i]==-1)
tarjan(i);
tt=0;

/*printf("\n");
for(i=1;i<=sum;++i)
printf("%d ",sun[i]);
printf("\n");*/

for(i=1;i<=sum;++i)
tt+=(sun[i]-1);
//printf("arr=%d tt=%d\n",arr,tt);
return tt<=arr;
}

int work()
{
int l=0,r=alln,mid,ans=alln;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}

int main(){

//freopen("T3.in","r",stdin);

rint i;

}