# 5.28联考题解

A bzoj3777

（可以发现其实顺时针旋n个不变时的方案数就是上面算的不考虑本质不同的方案数）

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

int gcd(int a,int b){return !a?b:gcd(b%a,a);}
const int maxn = 210000;
const int mod  = 1e9+7;
inline void add(int &a,const int &b){a+=b;if(a>=mod)a-=mod;}
inline void dec(int &a,const int &b){a-=b;if(a<0)a+=mod;}

int pw(int x,int k)
{
int re=1;
for(;k;k>>=1,x=(ll)x*x%mod) if(k&1)
re=(ll)re*x%mod;
return re;
}
int inv(int x){ return pw(x,mod-2); }

int n,K;
int f[maxn],s[maxn],g[maxn];

int main()
{
freopen("refrain.in","r",stdin);
freopen("refrain.out","w",stdout);

scanf("%d%d",&n,&K);
f[0]=1; s[0]=1;
for(int i=1;i<=n;i++)
{
f[i]=i-K<0?0:s[i-K];
s[i]=(s[i-1]+f[i])%mod;
}
g[0]=f[0];
for(int i=1;i<=n;i++) g[i]=(g[i-1]+s[i])%mod;

int ans=0,ansn=0;
for(int i=K;i<=n;i++)
{
if(i==n) ansn=ans;
int d=gcd(i,n); if(d<K) continue;
dec(ans,s[d-K]);
}
ansn=(ans-ansn+mod)%mod;
printf("%d\n%lld\n",ansn,(ll)ans*inv(n)%mod);

return 0;
}

B bzoj3778

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define db double
#define pb push_back
#define SZ(x) ((int)x.size())
using namespace std;

const int maxn = 105;
const double eps = 1e-7;

int n,m;
struct Point
{
int x,y,i;
friend inline bool operator ==(const Point &a,const Point &b){ return a.x==b.x&&a.y==b.y; }
friend inline Point operator -(const Point &a,const Point &b){return (Point){a.x-b.x,a.y-b.y};}
friend inline int operator *(const Point &a,const Point &b){return a.x*b.y-a.y*b.x;}
db Len() { return sqrt((db)x*x+(db)y*y); }
}p[maxn],pm[maxn],t[maxn]; int tp;
inline bool cmp(const Point &x,const Point &y)
{
return (x-t[0])*(y-x)>0;
}

int In_Line(const Point &x,const Point &y,const Point &q)
{
return (y-x)*(q-y)==0&&fabs((x-q).Len()+(y-q).Len()-(x-y).Len())<eps;
}
int In_Convex(const Point &x,const Point &y,const Point &z,const Point &q)
{
if(x==y) return In_Line(x,z,q);
return (y-x)*(q-y)>=0&&(z-y)*(q-z)>=0&&(x-z)*(q-x)>=0;
}

int ans;
vector<Point>v;

int f[maxn][maxn][maxn],pre[maxn][maxn][maxn];

int main()
{
//freopen("resonance.in","r",stdin);
//freopen("resonance.out","w",stdout);

scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y),p[i].i=i;
for(int i=1;i<=m;i++) scanf("%d%d",&pm[i].x,&pm[i].y);

ans=0;
for(int i=1;i<=n;i++)
{
t[0]=p[i];
tp=0; for(int j=1;j<=n;j++) if(p[j].y>p[i].y||(p[j].y==p[i].y&&p[j].x>p[i].x)) t[++tp]=p[j];
sort(t+1,t+tp+1,cmp);

for(int x=0;x<=tp;x++) for(int y=0;y<=tp;y++) for(int k=0;k<=tp;k++)
f[x][y][k]=pre[x][y][k]=-1;

f[0][0][0]=0;
for(int j=0;j<tp;j++)
{
Point tx=t[j+1];
for(int y=0;y<=j;y++)
{
Point ty=t[y];
int ok=1;
for(int k=1;k<=m&&ok;k++)
ok&=!In_Convex(t[0],ty,tx,pm[k]);

for(int x=0;x<=y;x++) if(f[j][x][y]!=-1)
{
if(f[j+1][x][y]<f[j][x][y])
f[j+1][x][y]=f[j][x][y],pre[j+1][x][y]=y;
}
}
}
for(int x=1;x<tp;x++) for(int y=x+1;y<=tp;y++) if(f[tp][x][y]>ans)
{
ans=f[tp][x][y]; v.clear();
v.pb(t[y]); v.pb(t[x]);
int ni=tp,px=x,py=y;
while(ni)
{
int ny=pre[ni][px][py];
if(ny!=py)
{
if(ny!=px) v.pb(t[ny]);
py=ny,swap(px,py);
}
ni--;
}
}
}

printf("%.2lf\n",ans/2.0);
/*printf("%d\n",SZ(v));
for(int i=0;i<SZ(v);i++)
{
printf("%d",v[i].i);
if(i+1!=SZ(v)) putchar(' ');
}putchar('\n');*/

return 0;
}

C bzoj3779

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define db double
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
using namespace std;

{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 210000;
const int maxd = 20;

int n,m;
struct edge{int y,nex;}a[maxn<<1]; int len,fir[maxn];
inline void ins(const int x,const int y){a[++len]=(edge){y,fir[x]};fir[x]=len;}

int root;
int cnt,dfn[maxn],siz[maxn],ff[maxn],df[maxn][maxd],dep[maxn];
void dfs(const int x)
{
for(int i=1;i<maxd;i++) df[x][i]=df[df[x][i-1]][i-1];
siz[x]=1; dfn[x]=++cnt;
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(y!=ff[x])
{
ff[y]=x; df[y][0]=x;
dep[y]=dep[x]+1;
dfs(y);
siz[x]+=siz[y];
}
}

struct Segment
{
ll seg[maxn<<2],flag[maxn<<2];
void pushdown(const int x,const int l,const int r)
{
if(!flag[x]) return;
int fl=flag[x]; flag[x]=0;
int mid=(l+r)>>1,lc=x<<1,rc=lc|1;

seg[lc]+=(ll)(mid-l+1)*fl; seg[rc]+=(ll)(r-mid)*fl;
flag[lc]+=fl; flag[rc]+=fl;
}
void pushup(const int x){seg[x]=seg[x<<1]+seg[x<<1|1];}
int lx,rx,c;
void upd(const int x,const int l,const int r)
{
if(rx<l||r<lx) return;
if(lx<=l&&r<=rx) { seg[x]+=(ll)(r-l+1)*c;flag[x]+=c;return; }
pushdown(x,l,r);
int mid=(l+r)>>1;
upd(x<<1,l,mid); upd(x<<1|1,mid+1,r);
pushup(x);
}
ll query(const int x,const int l,const int r)
{
if(rx<l||r<lx) return 0;
if(lx<=l&&r<=rx) return seg[x];
pushdown(x,l,r);
int mid=(l+r)>>1;
return query(x<<1,l,mid)+query(x<<1|1,mid+1,r);
}
void Upd(int x,int tc)
{
c=tc?1:-1;
if(dfn[root]>=dfn[x]&&dfn[root]<dfn[x]+siz[x])
{
lx=1,rx=dfn[x]-1; if(lx<=rx) upd(1,1,cnt);
lx=dfn[x]+siz[x],rx=cnt; if(lx<=rx) upd(1,1,cnt);
}
else lx=dfn[x],rx=dfn[x]+siz[x]-1,upd(1,1,cnt);
}
db q(int x)
{
ll ans=0; int Siz;
if(x==root)
{
Siz=n;
lx=1,rx=cnt,ans=query(1,1,cnt);
}
else if(dfn[root]>=dfn[x]&&dfn[root]<dfn[x]+siz[x])
{
int y=root; for(int i=maxd-1;i>=0;i--) if(dep[df[y][i]]>dep[x]) y=df[y][i];

Siz=n-siz[y];
lx=1,rx=dfn[y]-1; ans+=query(1,1,cnt);
lx=dfn[y]+siz[y],rx=cnt; if(lx<=rx) ans+=query(1,1,cnt);
}
else
{
Siz=siz[x];
lx=dfn[x],rx=dfn[x]+siz[x]-1,ans=query(1,1,cnt);
}
return (db)ans/Siz;
}
}seg;

{
int son[maxn][2],fa[maxn],rev[maxn];
void pushdown(int x)
{
if(rev[x])
{
rev[x]=0;
rev[son[x][0]]^=1,rev[son[x][1]]^=1;
swap(son[x][0],son[x][1]);
}
}
bool isrt(const int x){ return son[fa[x]][0]!=x&&son[fa[x]][1]!=x; }
void rot(int x)
{
int y=fa[x],z=fa[y];
if(!isrt(y)) son[z][son[z][1]==y]=x;
fa[x]=z;
int l=son[y][1]==x;
fa[son[y][l]=son[x][!l]]=y;
fa[son[x][!l]=y]=x;
}
int t[maxn],tp;
void splay(int x)
{
int tx=x; while(!isrt(tx)) t[++tp]=tx,tx=fa[tx]; t[++tp]=tx;
while(tp) pushdown(t[tp--]);

for(;!isrt(x);rot(x))
{
int y=fa[x],z=fa[y];
if(!isrt(y)) rot(((son[y][1]==x)^(son[z][1]==y))?x:y);
}
}
int go(int x,int dir)
{
pushdown(x);
while(son[x][dir])
{
x=son[x][dir];
pushdown(x);
}
return x;
}
void Access(int x)
{
int y=0;
for(;x;y=x,x=fa[x])
{
splay(x);
int ty=go(son[x][1],0);
if(ty) seg.Upd(dfn[x]>dfn[ty]?x:ty,1);
int nty=go(y,0);
if(nty) seg.Upd(dfn[x]>dfn[nty]?x:nty,0);

son[x][1]=y;
}
}
void makeroot(int x)
{
Access(x); splay(x); rev[x]^=1;
root=x;
}
void build(const int x)
{
for(int i=2;i<=n;i++) fa[i]=ff[i],seg.Upd(i,1);
}
}LCT;

char str[110];

int main()
{
//freopen("recompile.in","r",stdin);
//freopen("recompile.out","w",stdout);

for(int i=1;i<n;i++)
{
ins(x,y); ins(y,x);
}
dep[1]=1; dfs(root=1);
LCT.build(1);

for(int i=1;i<=m;i++)
{
if(str[2]=='L') LCT.Access(x);
else if(str[2]=='C') LCT.makeroot(x);
else printf("%.10lf\n",seg.q(x)+1.0);
}

return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120