noip模拟71[水]
noip模拟71 solutions
所以这套题是真的水,我差点就300分了!!!
T1 签到题
这个题我也不会证,就直接看度数是否可以整除这个颜色数
好像原因是二分图可以瞎搞
AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int n,m,k,c,ans;
int dn[N],dm[N];
signed main(){
#ifdef oj
freopen("qiandao.in","r",stdin);
freopen("qiandao.out","w",stdout);
#endif
scanf("%d%d%d%d",&n,&m,&k,&c);
fo(i,1,k){
int x,y;scanf("%d%d",&x,&y);
dn[x]++;dm[y]++;
}
fo(i,1,n)if(dn[i]%c)ans++;
fo(i,1,m)if(dm[i]%c)ans++;
printf("%d",ans);
}
T2 M弟娃
树剖+线段树+倍增
大板子
AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=3e5+5;
int n,m;
int to[N*2],nxt[N*2],head[N],rp;
void add_edg(int x,int y){
to[++rp]=y;
nxt[rp]=head[x];
head[x]=rp;
}
int siz[N],son[N],dep[N],fa[N],top[N];
int dfn[N],dfm[N],cnt;
int st[N][21];
void dfs_fi(int x,int f){
siz[x]=1;son[x]=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==f)continue;
dep[y]=dep[x]+1;fa[y]=x;
dfs_fi(y,x);
siz[x]+=siz[y];
if(!son[x]||siz[y]>siz[son[x]])son[x]=y;
}
}
void dfs_se(int x,int f){
top[x]=f;dfn[x]=++cnt;
st[x][0]=fa[x];
fo(i,1,20)st[x][i]=st[st[x][i-1]][i-1];
if(son[x])dfs_se(son[x],f);
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa[x]||y==son[x])continue;
dfs_se(y,y);
}
dfm[x]=cnt;
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
struct XDS{
#define ls x<<1
#define rs x<<1|1
int mx[N*5],tg[N*5];
void pushup(int x){
mx[x]=max(mx[ls],mx[rs]);
return ;
}
void pushdown(int x){
if(!tg[x])return ;
tg[ls]+=tg[x];
mx[ls]+=tg[x];
tg[rs]+=tg[x];
mx[rs]+=tg[x];
tg[x]=0;
return ;
}
void ins(int x,int l,int r,int ql,int qr){
if(ql>qr)return ;
if(ql<=l&&r<=qr){
tg[x]++;mx[x]++;
return ;
}
pushdown(x);
int mid=l+r>>1;
if(ql<=mid)ins(ls,l,mid,ql,qr);
if(qr>mid)ins(rs,mid+1,r,ql,qr);
pushup(x);return ;
}
#undef ls
#undef rs
}xds;
signed main(){
#ifdef oj
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
#endif
scanf("%d%d",&n,&m);
fo(i,1,n-1){
int x,y;scanf("%d%d",&x,&y);
add_edg(x,y);add_edg(y,x);
}
dep[1]=1;dfs_fi(1,0);dfs_se(1,1);
fo(i,1,m){
int x,y;scanf("%d%d",&x,&y);
int lca=LCA(x,y);
if(x==y)xds.ins(1,1,n,1,n);
else if(lca==x){
int now=y;
fu(j,20,0)if(dep[st[now][j]]>dep[lca])now=st[now][j];
//cout<<"zz"<<x<<" "<<y<<" "<<now<<" "<<lca<<" ";
//if(fa[now]==x||x==y)cout<<"sb";
xds.ins(1,1,n,1,dfn[now]-1);
xds.ins(1,1,n,dfm[now]+1,n);
//xds.ins(1,1,n,dfn[x],dfn[x]);
xds.ins(1,1,n,dfn[y],dfm[y]);
}
else if(lca==y){
int now=x;
fu(j,20,0)if(dep[st[now][j]]>dep[lca])now=st[now][j];
//cout<<"zz"<<x<<" "<<y<<" "<<now<<" "<<lca<<" ";
//if(fa[now]==y||x==y)cout<<"sb";
xds.ins(1,1,n,1,dfn[now]-1);
xds.ins(1,1,n,dfm[now]+1,n);
//xds.ins(1,1,n,dfn[y],dfn[y]);
xds.ins(1,1,n,dfn[x],dfm[x]);
}
else {
xds.ins(1,1,n,dfn[x],dfm[x]);
xds.ins(1,1,n,dfn[y],dfm[y]);
}
printf("%d\n",xds.mx[1]);
}
}
T3 变异大老鼠
就是一个树上的背包,我考场上竟然没有看出来
主要是我树都建好了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=305;
const int M=N*N;
const int inf=0x3f3f3f3f3f3f3f3f;
int n,m,k;
int edg[N][N],dis[N],who[N];
bool vis[N];
int to[N],nxt[N],head[N],rp;
void add_edg(int x,int y){
to[++rp]=y;
nxt[rp]=head[x];
head[x]=rp;
}
void redg(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;vis[1]=true;
fo(i,1,n)if(!vis[i]&&dis[i]>edg[1][i])dis[i]=edg[1][i],who[i]=1;
fo(j,2,n){
int mn=inf,wo;
fo(i,1,n){
if(vis[i])continue;
if(dis[i]<mn)mn=dis[i],wo=i;
}
vis[wo]=true;add_edg(who[wo],wo);
//cout<<who[wo]<<" "<<wo<<endl;
fo(i,1,n){
if(vis[i])continue;
if(dis[i]>dis[wo]+edg[wo][i])
dis[i]=dis[wo]+edg[wo][i],who[i]=wo;
}
}
}
double gl[N][N],ans;
double f[N][N],g[N][N];
void dfs(int x){
if(!head[x]){
fo(i,0,k)f[x][i]=gl[x][i];
return ;
}
int tot=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
dfs(y);
fu(o,k,0){
fo(j,0,o)
g[x][o]=max(g[x][o],g[x][o-j]+f[y][j]);
}
tot++;
}
fo(i,0,k)g[x][i]/=tot;
fo(i,0,k){
fo(j,i,k){
f[x][j]=max(f[x][j],gl[x][i]+(1.0-gl[x][i])*g[x][j-i]);
}
}
// cout<<x<<" ";
// fo(i,0,k)cout<<f[x][i]<<" ";cout<<endl;
}
signed main(){
#ifdef oj
freopen("arrest.in","r",stdin);
freopen("arrest.out","w",stdout);
#endif
scanf("%lld%lld%lld",&n,&m,&k);
memset(edg,0x3f,sizeof(edg));
fo(i,1,m){
int x,y,z;scanf("%lld%lld%lld",&x,&y,&z);
edg[x][y]=edg[y][x]=min(edg[y][x],z);
}
fo(i,1,n)fo(j,1,k)scanf("%lf",&gl[i][j]);
redg();dfs(1);ans=f[1][k];
printf("%.6lf",ans);
}
T4 朝鲜时蔬
就是测试点分治,直接推式子就好了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int mod=1e9+7;
int n,m,k,ans;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;y>>=1;
}return ret;
}
int jc[10];
signed main(){
#ifdef oj
freopen("vegetable.in","r",stdin);
freopen("vegetable.out","w",stdout);
#endif
scanf("%lld%lld%lld",&n,&m,&k);
jc[0]=1;fo(i,1,m)jc[i]=jc[i-1]*i%mod;
if(m==k){
n%=mod;ans=1;
fo(i,0,m-1)ans=ans*(n-i)%mod;
ans=ans*ksm(jc[m],mod-2)%mod;
}
if(m==2&&k==1){
int l=1,r;
while(l<=n){
r=n/(n/l);
ans=(ans+(r-l+1)%mod*(n/l-1)%mod)%mod;
l=r+1;
}
}
if(m==3&&k==1){
ans=(n/3)%mod;
}
if(m==3&&k==2){
int l=1,r;
while(l<=n){
r=n/(n/l);
int a=l-1>>1,b=r-1>>1;
int res=(a+b)%mod*((b-a+1)%mod)%mod;
if((l^1)&1)res=(res-a%mod+mod)%mod;
if(r&1)res=(res-b%mod+mod)%mod;
ans=(ans+res%mod*((n/l)%mod)%mod)%mod;
l=r+1;
}
}
if(m==4&&k==1){
if(n==4||n==5)ans=1;
else ans=((n/6)%mod+(n/9)%mod+(n/10)%mod+(n/12)%mod+(n/15)%mod+(n/21)%mod)%mod;
}
if(m==4&&k==2){
switch(n){
case 4:ans=1;break;
case 5:ans=1;break;
case 6:ans=1;break;
case 7:ans=3;break;
case 8:ans=6;break;
case 9:ans=9;break;
case 10:ans=10;break;
}
if(n>10)ans=((n/11)%mod+(n/29)%mod)%mod;
}
if(m==4&&k==3){
if(n==4)ans=1;
else if(n==5)ans=5;
else {
int l=1,r;
while(l<=n){
r=n/(n/l);
int a=l-1>>1,b=r-1>>1;
int res=(a+b)%mod*((b-a+1)%mod)%mod;
if((l^1)&1)res=(res-a%mod+mod)%mod;
if(r&1)res=(res-b%mod+mod)%mod;
res=(mod-res*3%mod)%mod;
res=(res+((r/3)-((l-1)/3))*2%mod)%mod;
res=(res+r%mod*((r-1)%mod)%mod*((r-2)%mod)%mod*ksm(jc[3],mod-2)%mod)%mod;
res=(res+mod-(l-1)%mod*((l-2)%mod)%mod*((l-3)%mod)%mod*ksm(jc[3],mod-2)%mod)%mod;
res=res*ksm(6,mod-2)%mod;
ans=(ans+res%mod*((n/l)%mod)%mod)%mod;
l=r+1;
}
}
}
printf("%lld",ans);
}
QQ:2953174821