比赛的时候开G开了3h结果rose说一句那唯一一个AC的是羊的心态就崩了。。

这套题感觉质量挺好然后就back了下

A: AI robots

有三个限制条件;相互能够看见和智商的差。使用主席树,可以维护两个状态,分别是其中一个“看见”和“智商”,这样的做法就无法利用K<=20的条件了。

利用扫描线+线段树,可以解决相互看见的约束(大概是我做过最神的扫描线了)对于一个点,处理出它能够看见的最前和最后点,和它的位置一起当做一条线,最前点加入这个点的位置,最后点删除这个点的影响,点的位置的线相当于一个询问,所以处理的顺序就是加入、询问、去除。解决了这点,显而易见的做法就是对于每个智商建一棵线段树暴力修改。每次插入一条链(与主席树类似的做法)可以防止空间溢出

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL; struct robot{int pos,r,iq;}rb[];
int poslen,pos[],iqlen,iq[]; struct line
{
int op,l,r,pos,iq;
line(){}
line(int OP,int L,int R,int POS,int IQ){op=OP,l=L,r=R,pos=POS,iq=IQ;}
}li[];int lilen;
bool cmp(line l1,line l2){return l1.pos==l2.pos?l1.op<l2.op:l1.pos<l2.pos;} struct trnode
{
int lc,rc;LL c;
}tr[];int trlen,rt[];
int change(int now,int L,int R,int p,LL c)
{
if(now==)
{
now=++trlen;
tr[now].lc=tr[now].rc=tr[now].c=;
}
if(L==R)tr[now].c+=c;
else
{
int mid=(L+R)/;
if(p<=mid)tr[now].lc=change(tr[now].lc,L,mid,p,c);
else tr[now].rc=change(tr[now].rc,mid+,R,p,c);
tr[now].c=tr[tr[now].lc].c+tr[tr[now].rc].c;
}
return now;
}
LL getsum(int now,int L,int R,int l,int r)
{
if(now==||(L==l&&R==r))return tr[now].c; int mid=(L+R)/;
int lc=tr[now].lc,rc=tr[now].rc; if(r<=mid) return getsum(lc,L,mid,l,r);
else if(mid+<=l)return getsum(rc,mid+,R,l,r);
else return getsum(lc,L,mid,l,mid)+getsum(rc,mid+,R,mid+,r);
} int main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
int n,K;
scanf("%d%d",&n,&K); poslen=,iqlen=;
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&rb[i].pos,&rb[i].r,&rb[i].iq);
pos[++poslen]=rb[i].pos;
iq[++iqlen]=rb[i].iq;
}
sort(pos+,pos+poslen+);
poslen=unique(pos+,pos+poslen+)-pos-;
sort(iq+,iq+iqlen+);
iqlen=unique(iq+,iq+iqlen+)-iq-; //----------------------LSH------------------------------- lilen=;
for(int i=;i<=n;i++)
{
int p=lower_bound(pos+,pos+poslen+,rb[i].pos)-pos;
int L=lower_bound(pos+,pos+poslen+,rb[i].pos-rb[i].r)-pos;
int R=upper_bound(pos+,pos+poslen+,rb[i].pos+rb[i].r)-pos-;
li[++lilen]=line(,p,,L,rb[i].iq);
li[++lilen]=line(,L,R,p,rb[i].iq);
li[++lilen]=line(,p,,R,rb[i].iq);
}
sort(li+,li+lilen+,cmp); //-------------------------preprare------------------------------ LL ans=;
trlen=;memset(rt,,sizeof(rt));
for(int i=;i<=lilen;i++)
{
if(li[i].op==)
{
int q=lower_bound(iq+,iq+iqlen+,li[i].iq)-iq;
rt[q]=change(rt[q],,n,li[i].l,);
}
else if(li[i].op==)
{
int q=lower_bound(iq+,iq+iqlen+,li[i].iq)-iq;
rt[q]=change(rt[q],,n,li[i].l,-);
}
else
{
int L=lower_bound(iq+,iq+iqlen+,li[i].iq-K)-iq;
int R=upper_bound(iq+,iq+iqlen+,li[i].iq+K)-iq-;
for(int j=L;j<=R;j++)
ans+=getsum(rt[j],,n,li[i].l,li[i].r);
ans--;
}
}
printf("%I64d\n",ans/);
return ;
}

A: AI robots

B: Hyperspace Highways

我比较菜并不会圆方树,所以就去学了学(所以我就不在这里讲了)

这个东西怎么和我之前做freda的传呼机用的方法那么像啊

题目给了个很有意思的性质,就是在一个点双里面的点距离为1,那么直接广义圆方树,答案就是树上距离/2

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std; struct node
{
int x,y,next;
}e[];int elen,elast[];
void eins(int x,int y)
{
elen++;
e[elen].x=x;e[elen].y=y;
e[elen].next=elast[x];elast[x]=elen;
}
int z,dfn[],low[];
int top,sta[]; int cnt;
vector<int>vec[];
void V_DCC(int x)
{
dfn[x]=low[x]=++z;
sta[++top]=x;
for(int k=elast[x];k;k=e[k].next)
{
int y=e[k].y;
if(dfn[y]==)
{
V_DCC(y);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
int k;cnt++;
do
{
k=sta[top];top--;
vec[cnt].push_back(k);
}while(k!=y);
vec[cnt].push_back(x);
}
}
else low[x]=min(low[x],dfn[y]);
}
} //--------------------------get_V-DCC--------------------------- node a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int id;
void composition(int n)//��һ�ù���Բ����
{
id=n;
len=;memset(last,,sizeof(last));
for(int i=;i<=cnt;i++)
{
id++;
for(int j=;j<vec[i].size();j++)
ins(id,vec[i][j]),ins(vec[i][j],id);
}
} int Bin[],dep[],f[][];
void dfs(int x)
{
for(int i=;Bin[i]<=dep[x];i++)f[i][x]=f[i-][f[i-][x]];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=f[][x])
{
f[][y]=x;
dep[y]=dep[x]+;
dfs(y);
}
}
}
int getdis(int x,int y)
{
if(dep[x]<dep[y])swap(x,y); int ret=;
for(int i=;i>=;i--)
if(dep[x]-dep[y]>=Bin[i])ret+=Bin[i],x=f[i][x];
if(x==y)return ret; for(int i=;i>=;i--)
if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])
ret+=Bin[i]*, x=f[i][x], y=f[i][y];
return ret+;
} int main()
{
int n,m,Q,x,y;
scanf("%d%d%d",&n,&m,&Q);
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
eins(x,y),eins(y,x);
} z=top=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
V_DCC(); composition(n);
Bin[]=;for(int i=;i<=;i++)Bin[i]=Bin[i-]*;
f[][]=;dep[]=;dfs(); while(Q--)
{
scanf("%d%d",&x,&y);
printf("%d\n",getdis(x,y)/);
}
return ;
}

B: Hyperspace Highways

C: Space Formula

水水的贪心决策包容性,首先自己肯定选最大的,然后大到小枚举,一个大的如果连最小的和它匹配都无法比当前小,就直接不管,因为有单调性所以这样肯定最优

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int a[],p[];
int main()
{
int n,id,K;
scanf("%d%d",&n,&id);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<=n;i++)scanf("%d",&p[i]);
K=p[]+a[id]; int ans=;
for(int i=,j=n;i<=n;i++,j--)
{
if(i==id)continue;
if(a[i]+p[j]>K)
{
ans++;
j++;
}
}
printf("%d\n",ans);
return ;
}

C: Space Formula

D: Interstellar battle

好题。让我对概率与期望的理解又加深了。

设剩下V个点,E条边,那么会剩下V-E个联通分量

总的期望=E(V-E) (联通分量个数)=E(V) (点的个数) - E(E) (边的条数)= sigema p(v)-sigema p(u)p(v)

两个东西分开算一下

第一个很好搞。第二个其实就是所有的边,因为修改是会把一个点所有的边都改了的,那我们让根节点管理所有儿子到它的边,那么修改一个点就只会影响当前点和他的父亲,O(1)修改,完了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int fa[];
double p[],f[];
void dfs(int x)
{
f[x]=;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=fa[x])
{
fa[y]=x;
dfs(y);
f[x]+=p[y];
}
}
} int main()
{
int n;
scanf("%d",&n); p[]=;
for(int i=;i<=n;i++)
scanf("%lf",&p[i]), p[i]=1.0-p[i]; len=;memset(last,,sizeof(last));
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);x++,y++;
ins(x,y),ins(y,x);
}
fa[]=;dfs(); double V=,E=;
for(int i=;i<=n;i++)
V+=p[i], E+=p[i]*f[i]; int Q;
scanf("%d",&Q);
while(Q--)
{
int x;double pp;
scanf("%d%lf",&x,&pp);
x++, pp=-pp; V-=p[x];
E-=p[x]*f[x];
E-=p[fa[x]]*f[fa[x]]; f[fa[x]]=f[fa[x]]-p[x];
p[x]=pp;
f[fa[x]]=f[fa[x]]+p[x]; V+=p[x];
E+=p[x]*f[x];
E+=p[fa[x]]*f[fa[x]]; printf("%.5lf\n",V-E);
}
return ;
}

D: Interstellar battle

E: Ancient civilizations

真的太感动了,做了一天的题终于过了!

首先先做一次凸包,假如是01交错一定无解

两种情况,一种是凸包上都是一种点,一种是0,1各1段

第一种,在凸包里面找一个不同的点,把凸包拆分成多个三角形

第二种,自己YY一下,画下图,相邻相同颜色的点去找不同颜色的点,可以发现固定选择一个边边的点然后拆分就可以保证不重不漏的把凸包画出来了

这样做有什么用呢?现在我们搞出来的三角形两个点同色,一个点不同色

假如这个三角形里面没有那个不同色的点,就可以直接连边了

否则还可以拆成三个三角形,不停递归下去就可以解决了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std; struct point{int x,y,op,id;}p[];
int multi(point p1,point p2,point p0)
{
int x1,y1,x2,y2;
x1=p1.x-p0.x;
y1=p1.y-p0.y;
x2=p2.x-p0.x;
y2=p2.y-p0.y;
return x1*y2-x2*y1;
}
bool cmp(point p1,point p2){return multi(p1,p2,p[])>;}
int aslen,asx[],asy[];
void pb(int x,int y){asx[++aslen]=x;asy[aslen]=y;} int n;
int top,sta[],insta[];
bool in_triangle(point p1,point p2,point p3,point p0)
{
int t1=multi(p1,p0,p2);
int t2=multi(p2,p0,p3);
int t3=multi(p3,p0,p1);
if((t1<&&t2<&&t3<)||(t1>&&t2>&&t3>))return true;
return false;
}
void separate(point p1,point p2,point p3,int L,int R)//p1,p2同色
{
if(L>R)return ;
int k=-;
for(int i=L;i<=R;i++)
if(p[i].op!=p1.op)
{
k=R;
if(insta[R]!=)
{
insta[i]=insta[R];
sta[insta[i]]=i;
insta[R]=;
}
swap(p[R],p[i]);
break;
}
pb(p3.id,p[k].id); //----------------找到分割点------------------------- int l=L,r=L-; bool bk=false;
for(int i=l;i<=R;i++)
if(i!=k)
{
if(in_triangle(p1,p2,p[k],p[i]))
{
if(p[i].op!=p1.op)bk=true;
r++;
if(insta[r]!=)
{
insta[i]=insta[r];
sta[insta[i]]=i;
insta[r]=;
}
swap(p[r],p[i]);
}
}
if(bk==false)
{
for(int i=l;i<=r;i++)
pb(p1.id,p[i].id);
}
else separate(p1,p2,p[k],l,r); //-------------------------------------------------- l=r+;bk=false;
for(int i=l;i<=R;i++)
if(i!=k)
{
if(in_triangle(p1,p3,p[k],p[i]))
{
if(p[i].op!=p3.op)bk=true;
r++;
if(insta[r]!=)
{
insta[i]=insta[r];
sta[insta[i]]=i;
insta[r]=;
}
swap(p[r],p[i]);
}
}
if(bk==false)
{
for(int i=l;i<=r;i++)
pb(p3.id,p[i].id);
}
else separate(p3,p[k],p1,l,r); //-------------------------------------------------- l=r+;bk=false;
for(int i=l;i<=R;i++)
if(i!=k)
{
if(in_triangle(p2,p3,p[k],p[i]))
{
if(p[i].op!=p3.op)bk=true;
r++;
if(insta[r]!=)
{
insta[i]=insta[r];
sta[insta[i]]=i;
insta[r]=;
}
swap(p[r],p[i]);
}
}
if(bk==false)
{
for(int i=l;i<=r;i++)
pb(p3.id,p[i].id);
}
else separate(p3,p[k],p2,l,r);
}
void graham()
{
top=;sta[++top]=,sta[++top]=;
memset(insta,,sizeof(insta));insta[]=,insta[]=;
for(int i=;i<=n;i++)
{
while(top>&&multi(p[sta[top]],p[i],p[sta[top-]])<=)
{
insta[sta[top]]=;
top--;
}
sta[++top]=i;insta[sta[top]]=top;
} //------------------------------------------------------ int s=;
for(int i=;i<=top;i++)
s+=(p[sta[i-]].op^p[sta[i]].op);
s+=(p[sta[]].op^p[sta[top]].op); if(s>)printf("Impossible\n");
else if(s==)
{
int cc=p[sta[]].op,k=-;
for(int i=;i<=n;i++)
if(insta[i]==&&p[i].op!=cc)
{
k=n;
if(insta[n]!=)
{
insta[i]=insta[n];
sta[insta[i]]=i;
insta[n]=;
}
swap(p[n],p[i]);
break;
} int L=,R=;
for(int i=;i<=top;i++)
{
pb(p[sta[i-]].id,p[sta[i]].id);
bool bk=false;
for(int j=L;j<=n;j++)
if(insta[j]==&&j!=k)
{
if(k==-||in_triangle(p[sta[i-]],p[sta[i]],p[k],p[j]))
{
if(p[j].op!=cc)bk=true;
R++;
if(insta[R]!=)
{
insta[j]=insta[R];
sta[insta[j]]=j;
insta[R]=;
}
swap(p[R],p[j]);
}
}
if(bk==false)
{
for(int j=L;j<=R;j++)
pb(p[sta[i]].id,p[j].id);
}
else separate(p[sta[i-]],p[sta[i]],p[k],L,R);
L=R+;
}
bool bk=false;
for(int j=L;j<=n;j++)
if(insta[j]==&&j!=k)
{
if(k==-||in_triangle(p[sta[top]],p[sta[]],p[k],p[j]))
{
if(p[j].op!=cc)bk=true;
R++;
if(insta[R]!=)
{
insta[j]=insta[R];
sta[insta[j]]=j;
insta[R]=;
}
swap(p[R],p[j]);
}
}
if(bk==false)
{
for(int j=L;j<=R;j++)
pb(p[sta[top]].id,p[j].id);
}
else separate(p[sta[top]],p[sta[]],p[k],L,R);
}
else //------------------------------------------------------------------
{
int be;bool bk=false;
for(int i=;i<=top;i++)
if(p[sta[i]].op==)
{
if(bk==false)
be=i, bk=true;
}
else bk=false; int L=,R=;
int i,k=(be-+top-)%top+;
for(i=be%top+;p[sta[i]].op==;i=i%top+)
{
int u=(i-+top-)%top+;
pb(p[sta[u]].id,p[sta[i]].id);
bool bk=false;
for(int j=L;j<=n;j++)
{
if(insta[j]==false&&in_triangle(p[sta[u]],p[sta[i]],p[sta[k]],p[j]))
{
if(p[j].op!=)bk=true;
R++;
if(insta[R]!=)
{
insta[j]=insta[R];
sta[insta[j]]=j;
insta[R]=;
}
swap(p[R],p[j]);
}
}
if(bk==false)
{
for(int j=L;j<=R;j++)
pb(p[sta[i]].id,p[j].id);
}
else separate(p[sta[u]],p[sta[i]],p[sta[k]],L,R);
L=R+;
} //---------------------------分别处理0和1--------------------------- ------- k=(i-+top-)%top+;
for(i=i%top+;i!=be;i=i%top+)
{
int u=(i-+top-)%top+;
pb(p[sta[u]].id,p[sta[i]].id);
bool bk=false;
for(int j=L;j<=n;j++)
{
if(insta[j]==false&&in_triangle(p[sta[u]],p[sta[i]],p[sta[k]],p[j]))
{
if(p[j].op!=)bk=true;
R++;
if(insta[R]!=)
{
insta[j]=insta[R];
sta[insta[j]]=j;
insta[R]=;
}
swap(p[R],p[j]);
}
}
if(bk==false)
{
for(int j=L;j<=R;j++)
pb(p[sta[i]].id,p[j].id);
}
else separate(p[sta[u]],p[sta[i]],p[sta[k]],L,R);
L=R+;
}
}
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].op),p[i].id=i-;
if(p[i].y<p[].y||(p[i].y==p[].y&&p[i].x<p[].x))
swap(p[i],p[]);
}
if(n==){printf("0\n");return ;}
else if(n==)
{ if(p[].op==p[].op)printf("1\n0 1\n");
else printf("0\n");
return ;
}
sort(p+,p+n+,cmp);
aslen=;graham(); if(aslen!=)
{
printf("%d\n",aslen);
for(int i=;i<=aslen;i++)
printf("%d %d\n",asx[i],asy[i]);
}
return ;
}

E: Ancient civilizations

F: Splitting money

全场最水题,模拟特判一下就完了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL; LL a[];
int main()
{
int n;LL x,f;
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%I64d",&a[i]);
scanf("%I64d%I64d",&x,&f); LL ans=;
for(int i=;i<=n;i++)
{
ans+=a[i]/(x+f);
a[i]%=(x+f);
if(a[i]>x)ans++;
} printf("%I64d\n",ans*f);
return ;
}

F: Splitting money

G: Space Isaac

转化模型太巧妙了!

对于一个数,表示它的方式是[0,x]区间头尾选和[x+1~m]区间头尾选。

无法表示当且仅当a数组里面的数都是两两匹配的

有一个想法就是建一个数组,让b[a[i]]=1,然后做马拉车

然而数的范围1e9不资瓷

但是这里只有0,1哦,把0的一段看做一个点,1看做一个点,0的段的长度就是两个相邻1的差

所以就差分之后做马拉车就好

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int a[],len,b[],p[];
int as[],aslen;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&a[i]); len=,b[++len]=-;
for(int i=;i<n;i++)
b[++len]=a[i+]-a[i], b[++len]=-;
b[len]=-; int k=;p[k]=;
for(int i=;i<=len;i++)
{
int Lk=k-p[k]+,Rk=k+p[k]-;
int j=k-(i-k); if(Lk<=j)p[i]=min(p[j],j-Lk+);
else p[i]=; while(b[i+p[i]]==b[i-p[i]]&&i-p[i]>&&i+p[i]<=len)p[i]++;
if(i+p[i]->Rk)k=i;
} for(int i=;i<n;i++)
{
if( (i==||p[i]>=i-) && (i==n-||p[i+n]>=n-i-) )
{
int d1=a[]+a[i],d2=a[i+]+a[n]-m;
if(d1==d2)as[++aslen]=d1;
}
}
if(p[n]>=n-)as[++aslen]=(a[]+a[n])%m; sort(as+,as+aslen+);
printf("%d\n",aslen);
for(int i=;i<aslen;i++)printf("%d ",as[i]);
if(aslen!=)printf("%d\n",as[aslen]);
return ;
}

G: Space Isaac

H: Palindrome Pairs

三水题的最后一道,明显状压然后暴力修改

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL; map<int,LL>mp;
char ss[];
bool v[];
int main()
{
int n;LL ans=;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
memset(v,,sizeof(v));
scanf("%s",ss+);int len=strlen(ss+);
for(int i=;i<=len;i++)
{
int x=ss[i]-'a';
v[x]^=;
}
int d=;
for(int i=;i<=;i++)
if(v[i]==)d|=(<<i);
ans+=mp[d];
for(int i=;i<=;i++)
ans+=mp[d^(<<i)];
mp[d]++;
}
printf("%I64d\n",ans);
return ;
}

H: Palindrome Pairs

I: Say Hello

dis去掉根号以后,和t构成了一个二次函数,解这个二次函数分类讨论即可

(有点码农但是和E比起来不算什么)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; double qg[][],qc[];
void guess()
{
for(int j=;j<=;j++)
{
for(int i=j;i<=;i++)
{
if(abs(qg[i][j])>1e-)
{
for(int k=;k<=;k++)swap(qg[i][k],qg[j][k]);
swap(qc[i],qc[j]);
break;
}
} for(int i=;i<=;i++)
{
if(i==j)continue;
double rate=qg[i][j]/qg[j][j];
for(int k=j;k<=;k++)qg[i][k]-=qg[j][k]*rate;
qc[i]-=qc[j]*rate;
}
}
} int n,ans,now;bool bk;double d1,d2;
void change(double d,int w)
{
if(w==)
{
if(d>d2)now=,bk=true;
else if(d>d1)now=;
}
else
{
if(d<=d1)
{
if(bk==true)ans++,bk=false;
now=;
}
else if(d<=d2)now=;
}
}
double ax1,ay1,ax0,ay0,ax2,ay2;
double bx1,by1,bx0,by0,bx2,by2;
double getdis(double x1,double y1,double x2,double y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
void calc()
{
double dis1=getdis(ax1,ay1,bx1,by1);
double dis0=getdis(ax0,ay0,bx0,by0);
double dis2=getdis(ax2,ay2,bx2,by2);
qg[][]=0.0*0.0,qg[][]=0.0,qg[][]=1.0,qc[]=dis1;
qg[][]=0.5*0.5,qg[][]=0.5,qg[][]=1.0,qc[]=dis0;
qg[][]=1.0*1.0,qg[][]=1.0,qg[][]=1.0,qc[]=dis2;
guess(); double a=qc[]/qg[][],b=qc[]/qg[][],c=qc[]/qg[][];
if(fabs(a)<=1e-&&fabs(b)<=1e-)return ; if(fabs(a)<=1e-)
{
if(b>)change(dis2,);
else change(dis2,);
}
else
{
if(<=-b/(2.0*a)&&-b/(*a)<=)
{
double mdis=((4.0*a*c)-b*b)/(4.0*a);
if(mdis>=)
{
if(a>)change(mdis,),change(dis2,);
else change(mdis,),change(dis2,);
}
else
{
if(a>)change(,),change(mdis,),change(,),change(dis2,);
}
}
else if(-b/(*a)<)
{
if(a>)change(dis2,);
else change(dis2,);
}
else
{
if(a>)change(dis2,);
else change(dis2,);
}
}
} int main()
{
scanf("%d%lf%lf",&n,&d1,&d2);d1*=d1,d2*=d2; scanf("%lf%lf",&ax1,&ay1);
scanf("%lf%lf",&bx1,&by1); int dis=getdis(ax1,ay1,bx1,by1); ans=;
if(dis<=d1)ans++,now=,bk=false;
else if(dis<=d2)now=,bk=true;
else now=,bk=true; for(int i=;i<=n;i++)
{
scanf("%lf%lf",&ax2,&ay2);
scanf("%lf%lf",&bx2,&by2);
ax0=(ax1+ax2)/,ay0=(ay1+ay2)/;
bx0=(bx1+bx2)/,by0=(by1+by2)/; calc(); ax1=ax2,ay1=ay2;
bx1=bx2,by1=by2;
}
printf("%d\n",ans);
return ;
}

I: Say Hello

J: Self-exploration

观察一波性质可以发现c01=c10时1的块数比0的多1,而且0的块数为c01

若c01=c10-1块数相同为c10,其他情况不合法

再加上c00和c11,可以把0的个数和1的个数都算出来

然后类似数位DP的做法,前后界相减

数位DP时,对于当前位是0,那么直接取没办法搞别的

1的话,这一位取0后面就可以随便取,而取的方案数是可以组合数搞出来的。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1e9+; char sa[],sb[];
void jian()
{
int len=strlen(sa+),tp;
for(int i=len;i>=;i--)
if(sa[i]==''){tp=i;break;}
sa[tp]='';
for(int i=tp+;i<=len;i++)sa[i]='';
if(tp==)
{
for(int i=;i<len;i++)sa[i]=sa[i+];
sa[len]='\0';
}
}
void exgcd(LL a,LL b,LL &x,LL &y)
{
if(a==)
{
x=,y=;
return ;
}
else
{
LL tx,ty;
exgcd(b%a,a,tx,ty);
x=ty-b/a*tx;
y=tx;
}
}
LL getinv(LL A)
{
LL B=mod,x,y;
exgcd(A,B,x,y);
return (x%B+B)%B;
}
LL fac[],fac_inv[];
void init()
{
fac[]=; fac_inv[]=;
for(int i=;i<=;i++)
fac[i]=(fac[i-]*i)%mod, fac_inv[i]=getinv(fac[i]);
}
LL getC(int n,int m)//n+1������ֳ�m+1��
{
if(n<m)return ;
if(n==-&&m==-)return ;
if(n==&&m==-)return ;
return fac[n]*fac_inv[m]%mod*fac_inv[n-m]%mod;
} int len,a[];
int sumz,sumo,bckz,bcko;
int calc()
{
if(a[]==)return ;
if(len==)return ; int now_sumz=,now_sumo=,now_bckz=,now_bcko=,last=;
LL ans=;
for(int i=;i<=len;i++)
{
if(a[i]==)
{
if(last==)now_sumz++;
else last=,now_bckz++,now_sumz++;
}
else
{
int rem_sumz=sumz-now_sumz-,rem_sumo=sumo-now_sumo,rem_bckz=bckz-now_bckz-(last==),rem_bcko=bcko-now_bcko;
ans= (ans +
getC(rem_sumz-,rem_bckz+-)*getC(rem_sumo-,rem_bcko-)%mod +
getC(rem_sumz-,rem_bckz-)*getC(rem_sumo-,rem_bcko-)%mod )%mod; if(last==)now_sumo++;
else last=,now_bcko++,now_sumo++;
} if(now_sumz>sumz||now_bckz>bckz||now_sumo>sumo||now_bcko>bcko)break;
}
if(now_sumz==sumz&&now_bckz==bckz&&now_sumo==sumo&&now_bcko==bcko)ans++;
return ans;
} int main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
init();
scanf("%s",sa+);jian();
scanf("%s",sb+); int c00,c01,c10,c11;int tp=;
scanf("%d%d%d%d",&c00,&c01,&c10,&c11);
if(c10-c01>||c10-c01<){printf("0\n");return ;}
bckz=c10,sumz=c00+bckz;
bcko=c10+(c01==c10),sumo=c11+bcko; len=strlen(sa+);
if(len<sumz+sumo)a[]=;
else if(len>sumz+sumo){len=sumz+sumo;for(int i=;i<=len;i++)a[i]=;}
else {for(int i=;i<=len;i++)a[i]=sa[i]-'';}
LL d0=calc(); len=strlen(sb+);
if(len<sumz+sumo)a[]=;
else if(len>sumz+sumo){len=sumz+sumo;for(int i=;i<=len;i++)a[i]=;}
else {for(int i=;i<=len;i++)a[i]=sb[i]-'';}
LL d1=calc(); printf("%lld\n",((d1-d0)%mod+mod)%mod);
return ;
}

J: Self-exploration

codeforce1046 Bubble Cup 11 - Finals 题解的更多相关文章

  1. Bubble Cup 11 - Finals [Online Mirror, Div. 1]题解 【待补】

    Bubble Cup 11 - Finals [Online Mirror, Div. 1] 一场很好玩的题啊! I. Palindrome Pairs 枚举哪种字符出现奇数次. G. AI robo ...

  2. Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1

    Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1 C. Jumping Transformers 我会状压 DP! 用 \(dp[x][y][ ...

  3. Bubble Cup 8 finals I. Robots protection (575I)

    题意: 有一个正方形区域, 要求支持两个操作: 1.放置三角形,给定放置方向(有4个方向,直角边与坐标轴平行),直角顶点坐标,边长 2.查询一个点被覆盖了多少次 1<=正方形区域边长n<= ...

  4. Bubble Cup 8 finals H. Bots (575H)

    题意: 简单来说就是生成一棵树,要求根到每个叶子节点上的路径颜色排列不同, 且每条根到叶子的路径恰有n条蓝边和n条红边. 求生成的树的节点个数. 1<=n<=10^6 题解: 简单计数. ...

  5. Bubble Cup 8 finals G. Run for beer (575G)

    题意: 给定一个带权无向图,每条边的代价为边权/当前速度,每次到达一个新节点,速度都会除以10. 求0号点到n-1号点的最小代价,如果多解输出点数最少的解,输出代价.路径点数.路径经过的点. 1< ...

  6. Bubble Cup 8 finals F. Bulbo (575F)

    题意: 给定初始位置,查询n次区间,每次查询前可以花费移动距离的代价来移动, 查询时需要花费当前位置到区间内最近的点的距离,求最小代价. 1<=n<=5000,1<=所有位置< ...

  7. Bubble Cup 8 finals E. Spectator Riots (575E)

    题意: 一个长宽是100000单位的球场上有很多暴动的观众,每个观众都有一个速度v, 在一秒内,观众会等概率地移动到与原位置的曼哈顿距离<=v的地方(不会移动到界外). 你需要选取三个位置,这三 ...

  8. Bubble Cup 8 finals C. Party (575C)

    题意: 给定n个人,分两天晚上去夜总会开派对,要求每天恰好有n/2个人去,且每人去的夜总会各不相同. 每个人对不同的晚上不同的夜总会有不同的满意度,求一个方案使得所有人的满意度之和最大. 夜总会数量= ...

  9. Bubble Cup 8 finals B. Bribes (575B)

    题意: 给定一棵n个点和有向边构成的树,其中一些边是合法边,一些边是非法边, 经过非法边需要1的费用,并且经过之后费用翻倍. 给定一个长为m的序列,问从点1开始按顺序移动到序列中对应点的总费用. 1& ...

随机推荐

  1. Android ExpandableListView的使用详解

    ExpandableListView(可扩展的ListView) ExpandableListVivew是ListView的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组 ...

  2. 【译】x86程序员手册11- 4.1系统寄存器

    4.1 Systems Registers 系统寄存器 The registers designed for use by systems programmers fall into these cl ...

  3. Django中图片的上传并显示

    一.settings配置文件中配置 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'medias').replace('\\', ...

  4. CAD向控件注册一个命令(com接口VB语言)

    主要用到函数说明: MxDrawXCustomFunction::Mx_RegistUserCustomCommand 向控件注册一个命令,用户在命令行输入命令名这个字符串,就会触发执行命令事件 命令 ...

  5. Python3爬取前程无忧数据分析工作并存储到MySQL

    1.导入包import requests #取数from lxml import etree #用xpath解析import pymysql #连接数据库import chardet #自动获取编码2 ...

  6. Array.prototype.slice.call()的理解

    最近在看廖雪峰的JS课程,浏览器中的操作DOM的那一章,有这样一道题. JavaScript Swift HTML ANSI C CSS DirectX <!-- HTML结构 --> & ...

  7. 《程序设计基础》实验题目2 c文件读取(反序列化?) 链表排序

    题目: 每个学生的信息卡片包括学号.姓名和成绩三项.定义存储学生信息的单向链表的结点类型:编写函 数,由文件依次读入 n(n≥0)个学生的信息,创建一个用于管理学生信息的单向链表:编写函数,对 该链表 ...

  8. Spring MVC 笔记 概述

    学习笔记 模型:封装装程序数据 视图:渲染模型数据,一般来说就是输出HTML 控制:处理请求,构建模型并将其传递给视图进行渲染 以上三者均围绕DispatcherServlet设计,它处理所有的HTT ...

  9. Linux之内核管理及故障排错

    一.Centos6启动流程: 加电自检PSOT 引导加载器BootLoader MBR(GRUB第一阶段)||(GRUB第1.5阶段)(GRUB第2阶段) 加载内核(vmlinuz.initramfs ...

  10. RHEL6 配置Yum库

    在/mnt目录下创建子目录“/cdrom”(用于将iso文件挂载到此目录下) 镜像状态确定为“已连接”(“已连接”未勾选的情况下无法获得iso文件) 配置自动挂载文件 (系统开机时会主动读取“/etc ...