NOI模拟16
山东省选的day2,T1似乎挺签到的,但是我因为没有看出来一个结论于是就没哟写
T2有意思,我写了虚树+LCT,但是必须要离线,在luogu没有前途
T1 小N的独立集
这个原dp是一个经典dp,所以实际上就是个dp套dp
dp[i][j][k]表示走到i点时,选i最大是j的贡献,不选是k贡献
发现\(k>=j-v_i\),但是我们并不知道上界,但是我们发现当k>j是j就没有用了,所以我们可以只记录k
发现这样写比较难写,我们转换一下dp定义,dp[i][j][k]表示走到i点,强制不选i点的最大贡献是j,不强制的最大贡献是k
此时发现j的状态完全被k包含了,转移就非常的简洁了
AC_code
#include<bits/stdc++.h>
using namespace std;
#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--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1005;
const int mod=1e9+7;
int n,k;
struct E{int to,nxt;}e[N*2];
int head[N],rp;
void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
int dp[N][N*5][7],siz[N],g[2][N*5][7],ans[N*5];
void dfs(int x,int f){
siz[x]=1;
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==f)continue;
dfs(y,x);siz[x]+=siz[y];
}
int now=0;memset(g,0,sizeof(g));
fo(i,1,k)g[now][0][i]=1;
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;if(y==f)continue;
now^=1;memset(g[now],0,sizeof(g[now]));
fo(l,0,k*siz[x])fo(r,0,k)if(g[now^1][l][r]){
// cerr<<"SB"<<endl;
fo(p,0,k*siz[y])fo(q,0,k)if(dp[y][p][q]){
// cerr<<"SB"<<endl;
g[now][l+p+q][max(l+p+q,l+r+p)-(l+p+q)]=(g[now][l+p+q][max(l+p+q,l+r+p)-(l+p+q)]+g[now^1][l][r]*dp[y][p][q])%mod;
}
}
}
fo(l,0,k*siz[x])fo(r,0,k)dp[x][l][r]=g[now][l][r];
// cerr<<x<<" "<<dp[x][0][1]<<endl;
}
signed main(){
freopen("nset.in","r",stdin);
freopen("nset.out","w",stdout);
n=read();k=read();
fo(i,1,n-1){
int x=read(),y=read();
add_edg(x,y);add_edg(y,x);
}
dfs(1,0);
fo(i,0,k*n)fo(r,0,k){
ans[i+r]=(ans[i+r]+dp[1][i][r])%mod;
}
fo(i,1,k*n)printf("%lld\n",ans[i]);
return 0;
}
T2 无处存储
就是写一下我的LCT,正解我并不会
询问非常少,可以对询问建立虚树,所以离线,用LCT维护这个虚树
AC_code
#include<bits/stdc++.h>
using namespace std;
#define ui unsigned int
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
ui lak[14000010],now;
ui *fa,*siz,*dfn,*dep,*a;
ui id,n,m,A,B,C,a0;
ui *w,cw,*sta,tp;
struct Q{ui tp,x,y,v;}q[50001];
bool com(ui x,ui y){return dfn[x]<dfn[y];}
ui LCA(ui x,ui y){
if(dep[x]<dep[y])swap(x,y);
// bool fl=false;
// if(x==10&&y==2){
// cerr<<"SB"<<endl;
// fl=true;
// }
while(dep[x]>dep[y])x=fa[x];
// if(fl)cerr<<x<<" "<<y<<endl;
while(x!=y)x=fa[x],y=fa[y];
return x;
}
ui DIS(ui x,ui y){
ui ret=0,res=0;
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])x=fa[x],ret++;
while(x!=y)x=fa[x],y=fa[y],ret+=2;
return ret-1;
}
ui *lsh,*sz;
struct LCT{
struct POT{
ui son[2],fa;
ui vl,sz;bool rev;
}tr[400005];
ui pth[400005],pt,al,*sm,*tg;
void add_edg(ui x,ui y,ui z){
// cerr<<x<<" "<<y<<" "<<" "<<z<<endl;
// cerr<<lsh[x]<<" "<<lsh[y]<<endl;
tr[y].fa=++al;
tr[al].fa=x;
sz[al]=z;sz[x]=sz[y]=1;
}
void pushup(ui x){
sm[x]=sm[tr[x].son[0]]+sm[tr[x].son[1]]+tr[x].vl;
tr[x].sz=tr[tr[x].son[0]].sz+tr[tr[x].son[1]].sz+sz[x];
}
void pushr(ui x){
swap(tr[x].son[0],tr[x].son[1]);
tr[x].rev^=1;
}
void pusht(ui x,ui v){
tr[x].vl+=sz[x]*v;
sm[x]+=tr[x].sz*v;
tg[x]+=v;
}
void pushdown(ui x){
if(tr[x].rev){
if(tr[x].son[0])pushr(tr[x].son[0]);
if(tr[x].son[1])pushr(tr[x].son[1]);
tr[x].rev=0;
}
if(tg[x]){
if(tr[x].son[0])pusht(tr[x].son[0],tg[x]);
if(tr[x].son[1])pusht(tr[x].son[1],tg[x]);
tg[x]=0;
}
}
bool nroot(ui x){return tr[tr[x].fa].son[0]==x||tr[tr[x].fa].son[1]==x;}
bool get(ui x){return tr[tr[x].fa].son[1]==x;}
void rotate(ui x){
ui y=tr[x].fa,z=tr[y].fa;
ui xpos=get(x),ypos=get(y);
if(nroot(y))tr[z].son[ypos]=x;
tr[x].fa=z;tr[y].fa=x;
tr[y].son[xpos]=tr[x].son[xpos^1];
tr[tr[y].son[xpos]].fa=y;
tr[x].son[xpos^1]=y;
pushup(y);pushup(x);
}
void splay(ui x){
ui now=x;pth[++pt]=x;
while(nroot(now))pth[++pt]=now=tr[now].fa;
while(pt)pushdown(pth[pt--]);
while(nroot(x)){
ui y=tr[x].fa;
if(nroot(y)){
if(get(x)==get(y))rotate(y);
else rotate(x);
}rotate(x);
}pushup(x);
}
void access(ui x){
for(ui y=0;x;y=x,x=tr[x].fa){
splay(x);tr[x].son[1]=y;pushup(x);
}
}
void makeroot(ui x){
access(x);splay(x);pushr(x);
}
void split(ui x,ui y){
makeroot(x);access(y);splay(y);
}
}lct;
ui iid(ui x){return lower_bound(lsh+1,lsh+cw+1,x)-lsh;}
void build_vtree(){
// cerr<<cw<<endl;fo(i,1,cw)cerr<<w[i]<<endl;
sort(w+1,w+cw+1,com);cw=unique(w+1,w+cw+1)-w-1;
// cerr<<cw<<endl;fo(i,1,cw)cerr<<w[i]<<endl;
ui nn=cw;fo(i,1,nn-1)w[++cw]=LCA(w[i],w[i+1]);//cerr<<w[cw]<<" "<<w[i]<<" "<<w[i+1]<<endl;
sort(w+1,w+cw+1,com);cw=unique(w+1,w+cw+1)-w-1;
// cerr<<"ZZ"<<endl;
// cerr<<cw<<endl;fo(i,1,cw)cerr<<w[i]<<endl;
fo(i,1,cw)lsh[i]=w[i];
sort(lsh+1,lsh+cw+1);
// cerr<<w[1]<<endl;
sta[tp=1]=w[1];lct.al=cw;
fo(i,2,cw){
// cerr<<i<<" "<<cw<<endl;
ui lca=LCA(sta[tp],w[i]);
if(lca!=sta[tp]){
while(dfn[lca]<dfn[sta[tp-1]]){
// cerr<<sta[tp-1]<<" "<<sta[tp]<<" "<<iid(sta[tp])<<endl;
lct.add_edg(iid(sta[tp-1]),iid(sta[tp]),DIS(sta[tp-1],sta[tp]));
tp--;
}
// cerr<<lca<<" "<<sta[tp]<<endl;
if(dfn[lca]!=dfn[sta[tp-1]]){
// cerr<<lca<<" "<<sta[tp]<<endl;
lct.add_edg(iid(lca),iid(sta[tp]),DIS(lca,sta[tp]));
sta[tp]=lca;
}
else lct.add_edg(iid(lca),iid(sta[tp]),DIS(lca,sta[tp])),tp--;
}
sta[++tp]=w[i];
}
fo(i,1,tp-1){
// cerr<<sta[i]<<" "<<sta[i+1]<<endl;
lct.add_edg(iid(sta[i]),iid(sta[i+1]),DIS(sta[i],sta[i+1]));
}
a=dfn;a[0]=a0;fo(i,1,n)a[i]=a[i-1]*a[i-1]*A+a[i-1]*B+C;
// cerr<<"SB"<<endl;
fo(i,1,cw){
// cerr<<i<<" "<<cw<<endl;
lct.tr[i].vl=a[lsh[i]];
if(lct.tr[i].fa){
ui ok=lsh[lct.tr[lct.tr[i].fa].fa],now=fa[lsh[i]];
// cerr<<lsh[i]<<" "<<fa[lsh[i]]<<" "<<lct.tr[i].fa<<" "<<ok<<endl;
while(now!=ok){
// cerr<<now<<endl;
lct.tr[lct.tr[i].fa].vl+=a[now];
now=fa[now];
}
}
}
}
void sol1(){
// cerr<<"SB"<<endl;
dfn=lak+now;now+=n+5;
siz=lak+now;now+=n+5;
fu(i,n,1)siz[i]++,siz[fa[i]]+=siz[i];
fo(i,1,n){
dfn[i]=dfn[fa[i]]+1;
if(fa[i])dfn[fa[i]]+=siz[i];
}
// cerr<<"SB"<<endl;
fo(i,1,n)dfn[i]-=siz[i]-1;//cerr<<dfn[i]<<" ";cerr<<endl;
w=lak+now;now+=m*4+5;
fo(i,1,m){
scanf("%u%u%u",&q[i].tp,&q[i].x,&q[i].y);
if(q[i].tp==0)scanf("%u",&q[i].v);
w[++cw]=q[i].x;w[++cw]=q[i].y;
// cerr<<q[i].x<<" "<<q[i].y<<endl;
}
// cerr<<w[1]<<endl;
// cerr<<"SB"<<endl;
dep=siz;fo(i,1,n)dep[i]=dep[fa[i]]+1;
sta=lak+now;now+=m*4+5;
// cerr<<cw<<endl;
lsh=lak+now;now+=m*4+5;
sz=lak+now;now+=m*8+5;
lct.sm=lak+now;now+=m*8+5;
lct.tg=lak+now;now+=m*8+5;
build_vtree();
// cerr<<"SB"<<endl;
fo(i,1,m){
if(q[i].tp==0){
lct.split(iid(q[i].x),iid(q[i].y));
lct.pusht(iid(q[i].y),q[i].v);
}
else {
lct.split(iid(q[i].x),iid(q[i].y));
// cerr<<iid(q[i].y)<<endl;
printf("%u\n",lct.sm[iid(q[i].y)]);
}
}
}
ui *tr1,*tr2;
void insert(ui x,ui v){
for(int i=x;i<=n;i+=(i&-i)){
tr1[i]+=v;tr2[i]+=v*(x-1);
}
}
void ins(ui l,ui r,ui v){
insert(l,v);insert(r+1,-v);
}
ui query(ui x){
ui ret=0;
for(int i=x;i;i-=(i&-i))ret+=tr1[i]*x-tr2[i];
return ret;
}
ui qry(ui l,ui r){
return query(r)-query(l-1);
}
void sol2(){
tr1=fa;tr2=lak+now;now+=n+2;
fo(i,0,n)tr1[i]=0;
fo(i,1,n){
a0=a0*a0*A+a0*B+C;
ins(i,i,a0);
}
while(m--){
ui tp,l,r,v;
scanf("%u%u%u",&tp,&l,&r);
if(l>r)swap(l,r);
if(tp==0){
scanf("%u",&v);
ins(l,r,v);
}
else printf("%u\n",qry(l,r));
}
}
ui Lca(int x,int y){
while(x!=y){
if(x<y)swap(x,y);
x=fa[x];
}return x;
}
void sol3(){
a=lak+now;
a[0]=a0;fo(i,1,n)a[i]=a[i-1]*a[i-1]*A+a[i-1]*B+C;
while(m--){
ui tp,l,r,v;
scanf("%u%u%u",&tp,&l,&r);
int lca=Lca(l,r);
if(tp==0){
scanf("%u",&v);
while(l!=lca)a[l]+=v,l=fa[l];
while(r!=lca)a[r]+=v,r=fa[r];
a[lca]+=v;
}
else {
int ans=0;
while(l!=lca)ans+=a[l],l=fa[l];
while(r!=lca)ans+=a[r],r=fa[r];
ans+=a[lca];
printf("%u\n",ans);
}
}
}
signed main(){
freopen("problemprovidercreep.in","r",stdin);
freopen("problemprovidercreep.out","w",stdout);
// cerr<<(sizeof(lak)+sizeof(q)+sizeof(lct)>>20)<<endl;
scanf("%u%u%u",&id,&n,&m);
scanf("%u%u%u%u",&A,&B,&C,&a0);
fa=lak;now+=n+5;
fo(i,2,n)scanf("%u",&fa[i]);
if(id==1)sol1();
if(id==2)sol3();
if(id==3)sol1();
if(id==4)sol1();
if(id==5)sol1();
if(id==6)sol1();
if(id==7)sol2();
if(id==8)sol2();
if(id==9)sol2();
if(id==10)sol1();
if(id==11)sol1();
if(id==12)sol1();
if(id==13)sol1();
if(id==14)sol2();
if(id==15)sol2();
if(id==16)sol2();
if(id==17)sol1();
if(id==18)sol1();
if(id==19)sol1();
if(id==20)sol1();
if(id==21)sol3();
if(id==22)sol3();
if(id==23)sol3();
if(id==24)sol1();
if(id==25)sol1();
if(id==26)sol1();
if(id==27)sol1();
if(id==28)sol3();
if(id==29)sol3();
if(id==30)sol3();
if(id==31)sol1();
if(id==32)sol1();
if(id==33)sol1();
if(id==34)sol1();
if(id==35)sol3();
if(id==36)sol3();
if(id==37)sol3();
if(id==38)sol1();
if(id==39)sol1();
if(id==40)sol1();
if(id==41)sol1();
if(id==42)sol3();
if(id==43)sol3();
if(id==44)sol3();
return 0;
}
QQ:2953174821