noip模拟4
A. 随
B. 单
这道题是一道树形动态规划..
有用到换根和前缀和的思想..
上次考试就有树规,可惜我考完试之后自以为是..只打了高斯消元..
结果这次还是用的高斯消元 —— 40 pts —— RE
希望自己的考场应对能力可以强亿点点..
B_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define lf double
#define re register ll
#define le strlen
const ll N=1000050;
const ll MAXN=500000;
const lf eps=1e-8;
inline void read(ll &ss)
{
ss=0;
ll cit=0;
char ch;
ch=getchar();
while((ch>'9') or (ch<'0'))
{
if(ch=='-') cit=1;
ch=getchar();
}
while((ch<='9') and (ch>='0'))
{
ss=(ss<<3)+(ss<<1)+(ch^48);
ch=getchar();
}
if(cit) ss=-ss;
}
ll n;
ll m;
ll ts;
ll alls;
ll crit;
ll from,arrival;
ll ta[N+50];
ll tb[N+50];
ll f[N+50];
ll sum[N+50];
ll vis[N+50];
struct Single
{
ll u;
ll v;
ll w;
ll nxt;
}a[N];
inline void add(ll u,ll v)
{
a[++ts].u=u;
a[ts].v=v;
a[ts].nxt=f[u];
f[u]=ts;
}
ll lowdfs(ll now,ll depth)
{
tb[1]+=ta[now]*depth;
sum[now]=ta[now];
vis[now]=1;
for(re i=f[now];i;i=a[i].nxt)
{
if(!vis[a[i].v]) sum[now]+=lowdfs(a[i].v,depth+1);
}
return sum[now];
}//A1
void moredfs(ll now,ll dad)
{
if(dad!=0) tb[now]=tb[dad]+sum[1]-sum[now]*2;
vis[now]=1;
for(re i=f[now];i;i=a[i].nxt)
{
if(!vis[a[i].v]) moredfs(a[i].v,now);
}
}//A2
void dfsmoreover(ll now,ll dad)
{
if(dad!=0) sum[1]+=tb[now]-tb[dad];
vis[now]=1;
for(re i=f[now];i;i=a[i].nxt)
{
if(!vis[a[i].v]) dfsmoreover(a[i].v,now);
}
}//B1
void dfsagain(ll now,ll dad)
{
if(dad!=0) sum[now]=(sum[1]-tb[now]+tb[dad])/2;
vis[now]=1;
for(re i=f[now];i;i=a[i].nxt)
{
if(!vis[a[i].v]) dfsagain(a[i].v,now);
}
}//B2
ll dfs(ll now)
{
ta[now]=sum[now];
vis[now]=1;
for(re i=f[now];i;i=a[i].nxt)
{
if(!vis[a[i].v]) ta[now]-=dfs(a[i].v);
}
return sum[now];
}//B3
inline void Worka()
{
for(re i=1;i<=n;++i)
{
read(ta[i]);
}
memset(vis,0,sizeof(vis));
lowdfs(1,0);
memset(vis,0,sizeof(vis));
moredfs(1,0);
for(re i=1;i<=n;i++)
{
printf("%lld ",tb[i]);
}
printf("\n");
return ;
}
inline void Workb()
{
for(re i=1;i<=n;++i)
{
read(tb[i]);
}
memset(vis,0,sizeof(vis));
sum[1]=2*tb[1];
dfsmoreover(1,0);
sum[1]=sum[1]/(n-1);
memset(vis,0,sizeof(vis));
dfsagain(1,0);
memset(vis,0,sizeof(vis));
dfs(1);
for(re i=1;i<=n;++i)
{
printf("%lld ",ta[i]);
}
printf("\n");
return ;
}
signed main()
{
read(alls);
while(alls)
{
alls--;
memset(ta,0,sizeof(ta));
memset(tb,0,sizeof(tb));
memset(sum,0,sizeof(sum));
memset(f,0,sizeof(f));
read(n);
for(re i=1;i<=n-1;++i)
{
read(from);
read(arrival);
add(from,arrival);
add(arrival,from);
}
read(crit);
if(crit==0) Worka();
else Workb();
}
return 0;
}
C. 题
卡特兰数板子
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
#define ll long long int
#define re register ll
#define lf double
#define lb lower_bound
#define ub upper_bound
#define mp make_pair
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x);
#define Copy(x,y) memset(y,x,sizeof x);
inline ll read()
{
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
const ll mod=1e9+7;
const ll N=2e5+51;
ll m,n,type,ans;
ll inv[N],fct[N];
ll f[N];
inline ll ksm(ll a,ll b,ll c){
a%=c; ll temp=1;
while(b){
if(b&1) temp=(temp*a)%c;
a=(a*a)%c; b>>=1;
}
return temp%c;
}
inline void Pre(){
fct[0]=1; inv[0]=1;
for(re i=1;i<=(n<<1);i++){
fct[i]=fct[i-1]*i%mod;
inv[i]=ksm(fct[i],mod-2,mod);
}
return ;
}
inline ll C(ll i,ll j){
if(j>i) return 1;
if(j<0) return 1;
return (fct[i]*inv[j])%mod*inv[i-j]%mod;
}
inline ll Cat(ll i){
if(i<0) return 0;
if(i==0) return 1;
return (C(i<<1,i)-C(i<<1,i-1)+mod)%mod;
}
inline void Work_Zero(){
for(re i=0;i<=n;i+=2){
(ans+=C(n,i)*C(i,i>>1)%mod*C((n-i),(n-i)>>1)%mod)%=mod;
}
printf("%lld",ans%mod);
}
inline void Work_One(){
ans=Cat(n>>1);
printf("%lld",ans%mod);
}
inline void Work_Two(){
f[0]=1;
for(re i=2;i<=n;i+=2){
for(re j=2;j<=i;j+=2){
(f[i]+=(((f[i-j]*Cat((j>>1)-1))%mod)<<2)%mod)%=mod;
}
}
printf("%lld",f[n]%mod);
}
inline void Work_Three(){
for(re i=0;i<=n;i+=2)
(ans+=C(n,i)*Cat(i>>1)%mod*Cat((n-i)>>1)%mod)%=mod;
printf("%lld",ans%mod);
}
signed main(){
n=read(); type=read();
if(n&1){ puts("0"); return 0; }
Pre();
if(type==0) Work_Zero();
if(type==1) Work_One();
if(type==2) Work_Two();
if(type==3) Work_Three();
return 0;
}
D. 大佬
调了很久,在此感谢 Varuxn 大佬对于错误的指出..
学会了 map 和 pair 的一些重要方法..
在这里写下一些值得注意的点..
- 无论是 dfs 还是 bfs,需要将最初的状态处理好..
不要兜兜转转回到起点..最后导致 WA 或者 TLE ..
或者在以后的代码中会调用到起点的状态,而因为没有处理好初始的状态导致自己后面的结果出现错误.. - 无论做什么题,一定要将思路完全透彻之后再去码题..
要不然可能自己带着错误的思路打了半天代码..就算看 TJ 也看不出自己的错误所在..
甚至还可能自己调了半天,哪怕是注意到了自己代码的某个地方,却也看不出 ta 是错误的.. - 初始化要定义好位置啊..不要急急忙忙最后吃不到热豆腐..
D_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define re register ll
#define mp make_pair
#define lf double
#define le strlen
const ll mod=1e9+7;
inline void read(ll &ss)
{
ss=0;
ll cit=0;
char ch;
ch=getchar();
while((ch>'9') or (ch<'0'))
{
if(ch=='-') cit=1;
ch=getchar();
}
while((ch<='9') and (ch>='0'))
{
ss=(ss<<3)+(ss<<1)+(ch^48);
ch=getchar();
}
if(cit) ss=-ss;
}
ll n,m,mc,ts;
ll a[20000];
ll w[20000];
ll c[20000];
map<ll,bool> force;
ll crit;
ll maxn;
ll rounds;
ll minn=1e9;
ll posi;
ll HP;
map<ll,bool> uniq;
ll dp[2000][2000];//单向攻击..
struct Fighting
{
ll step;
ll grade;
ll power;
}z[1000000],z2[1000000];
ll cnt;
map<pair<ll,ll>,bool> maplive;
inline void dfs()
{
deque<Fighting> que;
Fighting now;
que.push_back((Fighting){1,0,1});
maplive[mp(1,1)]=1;
while(!que.empty())
{
now=que.front();
que.pop_front();
if(now.step>=rounds) break;
que.push_back((Fighting){now.step+1,now.grade+1,now.power});
maplive[mp(now.step+1,now.power)]=1;
if(now.grade>1 and now.grade*now.power<=HP and maplive[mp(now.step+1,now.power*now.grade)]==0)
{
maplive[mp(now.step+1,now.power*now.grade)]=1;
que.push_back((Fighting){now.step+1,now.grade,now.grade*now.power});
z[++cnt].step=now.step+1;
z[cnt].power=now.grade*now.power;
}
}
return ;
}
inline bool cmp(Fighting aa,Fighting bb)
{
if(aa.power==bb.power)
return aa.step<bb.step;
return aa.power<bb.power;
}
signed main()
{
read(n);
read(m);
read(mc);
for(re i=1;i<=n;++i) read(a[i]);
for(re i=1;i<=n;++i) read(w[i]);
for(re i=1;i<=m;++i)
{
read(c[i]);
HP=max(HP,c[i]);
}
for(re i=1;i<=n;++i)
{
for(re j=mc;j>=a[i];--j)
{
dp[i][j-a[i]]=max(dp[i][j-a[i]],dp[i-1][j]+1);
dp[i][min(mc,j-a[i]+w[i])]=max(dp[i][min(mc,j-a[i]+w[i])],dp[i-1][j]);
}
}
for(re i=1;i<=n;i++)
{
for(re j=1;j<=mc;j++)
{
rounds=max(dp[i][j],rounds);
}
}
dfs();
ll tot=0;
sort(z+1,z+cnt+1,cmp);
for(re i=1;i<=cnt;++i)
{
if(force[z[i].power]==0)
{
z2[++tot]=z[i];
}
}
#define z z2
#define cnt tot
for(re i=1;i<=m;i++)
{
crit=0;
if(c[i]<=rounds)
{
putchar('1');
putchar('\n');
continue;
}
minn=(ll)INT_MAX;
for(re j=cnt,k=1;j>=1;--j)
{
while(k<cnt and z[k].power+z[j].power<=c[i])
{
if(minn>z[k].step-z[k].power)
{
minn=z[k].step-z[k].power;
posi=k;
}
k++;
}
if(z[j].power<=c[i] and z[j].power+rounds-z[j].step>=c[i])
{
crit=1;
break;
}
if(z[j].power+z[posi].power<=c[i] and z[j].power+rounds-z[j].step-minn>=c[i])
{
crit=1;
break;
}
}
if(crit==0)
{
putchar('0');
putchar('\n');
}
else
{
putchar('1');
putchar('\n');
}
}
return 0;
}