湖南雅礼培训 1.6

1.送你一个DAG

 

 

/*
    怀疑以前学了假的Strling数,看了一个很相似的题bzoj2159的题解,终于理解了本题的solution
    附bzoj2159大佬题解地址:http://blog.csdn.net/qq_33229466/article/details/73065525 
*/
#include<iostream>
#include<cstdio>
#include<queue>
#define maxn 200010
#define mod 998244353
using namespace std;
int n,m,K,num,head[maxn],du[maxn];
int f[maxn][510],strl[510][510];
struct node{
    int to,pre;
}e[maxn];
void Insert(int from,int to){
    e[++num].to=to;
    e[num].pre=head[from];
    head[from]=num;
}
queue<int>q;
int main(){
    scanf("%d%d%d",&n,&m,&K);
    int x,y;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        Insert(x,y);
        du[y]++;
    }
    q.push(1);
    f[1][0]=1;
    while(!q.empty()){
        int now=q.front();q.pop();
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            du[to]--;
            if(!du[to])q.push(to);
            for(int j=0;j<=K;j++)f[to][j]=(f[to][j]+f[now][j])%mod;
            for(int j=0;j<=K-1;j++)f[to][j+1]=(f[to][j+1]+1LL*f[now][j]*(j+1)%mod)%mod;
        }
    }
    strl[0][0]=1;
    for(int i=1;i<=K;i++)
    for(int j=1;j<=i;j++)
        strl[i][j]=(1LL*strl[i-1][j-1]+1LL*strl[i-1][j]*j)%mod;
    for(int i=1;i<=n;i++){
        int ans=0;
        for(int j=0;j<=K;j++)ans=(ans+1LL*f[i][j]*strl[K][j]%mod)%mod;
        ans=(ans+mod)%mod;
        printf("%d\n",ans);
    }
    return 0;
}
100分 Strling数

 

 

 

 

2.送你一棵圣诞树

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;
int pos[maxn],c[maxn],id[maxn],col[maxn],n,lastans,q,t,cnt,sz[maxn];
int num,head[maxn];
bool vis[maxn],v[maxn];
struct node{
    int to,pre;
}e[maxn*2];
void Insert(int from,int to){
    e[++num].to=to;
    e[num].pre=head[from];
    head[from]=num;
}
void dfs(int now){
    vis[now]=1;pos[now]=++cnt;id[cnt]=now;col[cnt]=c[now];
    sz[now]=1;
    for(int i=head[now];i;i=e[i].pre){
        int to=e[i].to;
        if(vis[to])continue;
        dfs(to);
        sz[now]+=sz[to];
    }
}
int ask(int rot,int l,int r){
    memset(v,0,sizeof(v));
    int res=0;
    for(int i=1,j=pos[rot];i<=sz[rot];i++,j++)
        if(col[j]<=r&&col[j]>=l&&!v[col[j]])res++,v[col[j]]=1;
    return res;
}
int qread(){
    int i=0,j=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')j=-1;ch=getchar();}
    while(ch<='9'&&ch>='0')i=i*10+ch-'0',ch=getchar();
    return i*j;
}
int main(){
//    freopen("Cola.txt","r",stdin);
    freopen("xmastree1.in","r",stdin);freopen("xmastree1.out","w",stdout);
    scanf("%d%d%d",&n,&q,&t);
    int x,y; 
    for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        Insert(x,y);Insert(y,x);
    }
    dfs(1);
    if(t==1){
        int opt,z;
        for(int i=1;i<=q;i++){
            scanf("%d",&opt);
            if(opt==1){
                scanf("%d%d%d",&x,&y,&z);
                x^=lastans;y^=lastans;z^=lastans;
                lastans=ask(x,y,z);
                printf("%d\n",lastans);
            }
            if(opt==2){
                scanf("%d%d",&x,&y);
                x^=lastans;y^=lastans;
                col[pos[x]]=y;
            }
        }
    }
    if(t==0){
        int opt,z;
        for(int i=1;i<=q;i++){
            scanf("%d",&opt);
            if(opt==1){
                scanf("%d%d%d",&x,&y,&z);
                lastans=ask(x,y,z);
                printf("%d\n",lastans);
            }
            if(opt==2){
                scanf("%d%d",&x,&y);
                col[pos[x]]=y;
            }
        }
    }
    return 0;
}
40分 暴力
/*
    人生第一篇树套树 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;
int num,head[maxn],dc=0;
int fa[maxn][20],idl[maxn],idr[maxn];
int n,q,type,col[maxn],croot[maxn];
struct node_{int to,pre;}e[maxn*2];
void Insert(int from,int to){e[++num].to=to;e[num].pre=head[from];head[from]=num;}
void dfs(int now){
    idl[now]=++dc;
    for(int i=head[now];i;i=e[i].pre){
        int to=e[i].to;
        if(to==fa[now][0])continue;
        fa[to][0]=now;
        for(int j=1;j<=17;j++)fa[to][j]=fa[fa[to][j-1]][j-1];
        dfs(to);
    }
    idr[now]=dc;
}
struct Segment_Tree{
    const static int Nod=3e7;
    int sum[Nod],lc[Nod],rc[Nod],node;
    void add(int &now,int L,int R,int x,int v){
        if(!now)now=++node;
        sum[now]+=v;
        int mid=(L+R)>>1;
        if(L^R)x<=mid?add(lc[now],L,mid,x,v):add(rc[now],mid+1,R,x,v);
    }
    int query(int now,int L,int R,int l,int r){
        if(!now||(l<=L&&R<=r))return sum[now];
        int res=0,mid=(L+R)>>1;
        if(l<=mid)res+=query(lc[now],L,mid,l,r);
        if(r>mid)res+=query(rc[now],mid+1,R,l,r);
        return res;
    }
}T;
struct B_I_T{
    int root[maxn];
    void add(int x,int y,int v){
        while(x<=n){
            T.add(root[x],1,n,y,v);
            x+=x&(-x);
        }
    }
    int sum(int r,int x,int y){
        int res=0;
        while(r){
            res+=T.query(root[r],1,n,x,y);
            r-=r&(-r);
        }
        return res;
    }
}BIT;
void modify(int now,int c,int v){
    int down=now;
    T.add(croot[c],1,n,idl[now],v);
    int s=v==-1?0:1;
    if(T.query(croot[c],1,n,idl[now],idr[now])!=s)return;
    for(int i=17;i>=0;i--){
        int f=fa[now][i];
        if(!f)continue;
        int val=T.query(croot[c],1,n,idl[f],idr[f]);
        if(val==s)now=f;
    }
    BIT.add(c,idl[down],v);
    if(now!=1)BIT.add(c,idl[fa[now][0]],-v);
}
int main(){
    freopen("xmastree9.in","r",stdin);freopen("Soda.txt","w",stdout);
    scanf("%d%d%d",&n,&q,&type);
    for(int i=1;i<=n;i++)scanf("%d",&col[i]);
    for(int i=2;i<=n;i++){
        int x,y;scanf("%d%d",&x,&y);
        Insert(x,y);Insert(y,x);
    }
    dfs(1);
    for(int i=1;i<=n;i++)modify(i,col[i],1);
    int lastans=0;
    while(q--){
        int ty,u;scanf("%d%d",&ty,&u);
        if(ty==1){
            int l,r;scanf("%d%d",&l,&r);
            if(type)u^=lastans,l^=lastans,r^=lastans;
            lastans=BIT.sum(r,idl[u],idr[u])-BIT.sum(l-1,idl[u],idr[u]);
            printf("%d\n",lastans);
        }
        else{
            int c;scanf("%d",&c);
            if(type)u^=lastans,c^=lastans;
            modify(u,col[u],-1);
            col[u]=c;
            modify(u,col[u],1);
        }
    }
    return 0;
}
100分 树状数组套线段树

 

3.送你一颗圣诞树

 

posted @ 2018-01-06 15:56  Echo宝贝儿  阅读(340)  评论(0编辑  收藏  举报