2020HDU多校第二场By Rynar 6763-6774

1001.Total Eclipse

思路:从大到小建树,利用并查集路径压缩

int n,m,k;
int a[N],rk[N],f[N],vis[N],fa[N];
vector<int>v[N];
int ff(int x){
    if (f[x]==x)return x;
    return f[x]=ff(f[x]);
}
bool cmp(int x,int y){
    return a[x]>a[y];
}
void solve(){
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        rk[i]=f[i]=i;
        fa[i]=vis[i]=0;
        v[i].clear();
    }
    sort(rk+1,rk+1+n,cmp);
    for (int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        v[x].push_back(y);v[y].push_back(x);
    }
    for (int i=1;i<=n;i++){
        int x=rk[i];
        vis[x]=1;
        for (int j:v[x]){
            if (vis[j]){
                int y=ff(j);
                if (x!=y){
                    fa[y]=f[y]=x;
                }
            }
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++)ans+=a[i]-a[fa[i]];
    printf("%lld\n",ans);
}
int main() {
    int T;
    cin>>T;
    while (T--)solve();
    return 0;
}

1002.Blood Pressure Game

1003.Count on a Tree II Striking Back

1004.Diamond Rush

1005.New Equipments

思路:zkw费用流,建图进行增广路

const int N=1e5+10;
const ll inf=1e16;
int n,m,k;
struct zkw{
    ll Cost=0,Flow=0;
    ll vis[N],dis[N],head[N];
    int step,n;
    struct node{
        ll to,cap,cost,n;
    }e[N<<1];
    void add(int x,int y,int v,ll c){
        e[step].to=y;
        e[step].cap=v;
        e[step].cost=c;
        e[step].n=head[x];
        head[x]=step++;
        e[step].to=x;
        e[step].cap=0;
        e[step].cost=-c;
        e[step].n=head[y];
        head[y]=step++;
    }
    bool spfa(int s,int t){
        for(int i=0;i<=n;i++) vis[i]=0,dis[i]=inf;//要改
        deque<int>q;
        q.push_back(t);
        dis[t]=0;
        vis[t]=1;
        while(!q.empty()){
            int u=q.front();
            q.pop_front();
            for(int i=head[u];~i;i=e[i].n){
                int v=e[i].to;
                if(e[i^1].cap&&dis[v]>dis[u]+e[i^1].cost){
                    dis[v]=dis[u]+e[i^1].cost;
                    if(!vis[v]){
                        vis[v]=1;
                        if(!q.empty()&&dis[v]<dis[q.front()])//SLF优化
                            q.push_front(v);
                        else q.push_back(v);
                    }
                }
            }
            vis[u]=0;
        }
        return dis[s]<inf;
    }
    int dfs(int s,int t,ll flow){
        vis[s]=1;
        if(s==t||flow<=0) return flow;
        int res,used=0;
        for(int i=head[s];~i;i=e[i].n){
            int v=e[i].to;
            if(!vis[v]&&e[i].cap&&dis[s]-dis[v]==e[i].cost){
                res=dfs(v,t,min(e[i].cap,flow-used));
                if(res) {
                    e[i].cap-=res;
                    e[i^1].cap+=res;
                    Cost+=res*e[i].cost;
                    used+=res;
                }
                if(used==flow)break;
            }
        }
        return used;
    }
    void solve(int s,int t){
        while(spfa(s,t)){
            vis[t]=1;
            while(vis[t]){
                for(int i=0;i<=n;i++) vis[i]=0;//要改
                Flow+=dfs(s,t,inf);
            }
        }
    }
    void init(int n){
        step=0;
        Flow=Cost=0;
        memset(head,-1,sizeof head);
        this->n=n;
    }
}zkw;
ll a[N],b[N],c[N],uni[N];
struct node{
	ll x,y,id;
	bool operator<(const node& k)const{
		return y==k.y?x<k.x:y<k.y;
	}
};
vector<node>p;
void solve(){
    ll n,m;
    scanf("%lld%lld",&n,&m);
    for (int i=1;i<=n;i++){
        scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
    }
    p.clear();
    int tot=n+2;
    for (int i=1;i<=n;i++){
        double dx=-0.5*b[i]/a[i];
        int l=floor(dx),r=ceil(dx);
        if (l==r)r++;if (l>m)l=m;if (r<=0)r=1;
        int cnt=tot;
        while (cnt>0){
            if (l>0){
                p.push_back({l,a[i]*l*l+b[i]*l+c[i],i-1});
                l--;cnt--;
            }
            if (r<=m){
                p.push_back({r,a[i]*r*r+b[i]*r+c[i],i-1});
                r++;cnt--;
            }
            if (l<=0&&r>m)break;
        }
    }
    sort(p.begin(),p.end());
    int s=0,t=3000;
    zkw.init(t+1);
    int cntp=p.size();
    for (int i=0;i<p.size();i++){
        uni[i]=p[i].x;
    }
    sort(uni,uni+cntp);
    cntp=unique(uni,uni+cntp)-uni;
    for (int i=0;i<p.size();i++) {
        p[i].x=lower_bound(uni,uni+cntp,p[i].x)-uni;
    }
    for (int i=1;i<=n;i++) {
        zkw.add(1,1+i,1,0);
    }
    for (int i=0;i<p.size();i++) {
        zkw.add(p[i].id+2,n+2+p[i].x,1,p[i].y);
    }
    for (int i=0;i<cntp;i++){
        zkw.add(n+2+i,t,1,0);
    }
    for (int i=0;i<n;i++){
        zkw.add(s,1,1,0);
        zkw.solve(s,t);
        if (i==n-1) printf("%lld\n",zkw.Cost);
        else printf("%lld ",zkw.Cost);
    }
}
int main(){
    int T;
    scanf("%d",&T);
    while (T--){
        solve();
    }
    return 0;
}

1006.The Oculus

思路:斐波那契数列循环节

const int N=2e6+10;
const ll mod=998244353;
int n,m,k;
int a[N],b[N],c[N];
ll f[N];
void solve(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++)scanf("%d",&a[i]);
    scanf("%d",&m);
    for (int i=1;i<=m;i++)scanf("%d",&b[i]);
    scanf("%d",&k);
    for (int i=1;i<=k;i++)scanf("%d",&c[i]);
    ll sa,sb,sc;sa=sb=sc=0;
    for (int i=1;i<=k;i++)if (c[i])sc=(sc+f[i])%mod;
    for (int i=1;i<=n;i++)if (a[i])sa=(sa+f[i])%mod;
    for (int i=1;i<=m;i++)if (b[i])sb=(sb+f[i])%mod;
    sc=(sa*sb%mod-sc+mod)%mod;
    c[k+1]=0;
    for (int i=1;i<=k;i++){
        if (sc==f[i]&&c[i-1]==0&&c[i]==0&&c[i+1]==0){
            printf("%d\n",&i);
            break;
        }
    }
}
int main(){
    int T;
    f[0]=1;f[1]=1;
    for (int i=1;i<N;i++)f[i+1]=(f[i]+f[i-1])%mod;
    cin>>T;
    while (T--){
        solve();
    }
    return 0;
}

1007.In Search of Gold

1008.Dynamic Convex Hull

1009.It's All Squares

1010.Lead of Wisdom

思路:暴搜

const int N=50+10;
int n,k;
struct node{
    int a,b,c,d;
};
ll ans=0;
vector<node>v[N],p[N];
void dfs(int x,int a,int b,int c,int d){
    if (x==k+1){
        ans=max(ans,1ll*(a+100)*(b+100)*(c+100)*(d+100));
        return;
    }
    for (node i:v[x]){
        dfs(x+1,a+i.a,b+i.b,c+i.c,d+i.d);
    }
}
void solve(){
    scanf("%d%d",&n,&k);
    for (int i=1;i<=k;i++)v[i].clear(),p[i].clear();
    ans=0;
    int t,a,b,c,d;
    for (int i=1;i<=n;i++){
        scanf("%d%d%d%d%d",&t,&a,&b,&c,&d);
        p[t].push_back({a,b,c,d});
    }
    int cnt=0,a1,b1,c1,d1;a1=b1=c1=d1=0;
    for (int i=1;i<=k;i++){
        if (p[i].size()==1){
            a1+=p[i][0].a;b1+=p[i][0].b;c1+=p[i][0].c;d1+=p[i][0].d;
        }
        else if (p[i].size()){
            v[++cnt]=p[i];
        }
    }
    k=cnt;
    dfs(1,a1,b1,c1,d1);
    printf("%lld\n",ans);
}
int main() {
    int T;
    cin>>T;
    while (T--)solve();
    return 0;
}

1011.King of Hot Pot

1012.String Distance

思路:序列自动机+dp

const int N=1e5+10;
const int inf=0x3f3f3f3f;
int n,m,k,q;
char s1[N],s2[N];
int nxt[N][27],dp[21][21];
void init(char *s){//序列自动机,nxt[i][j]记录i-len的第一个j出现的位置
    int len=strlen(s);
    for(int i=0;i<26;i++) nxt[len][i]=inf;
    for(int i=len-1;i>=0;i--){
        for(int j=0;j<26;j++)nxt[i][j]=nxt[i+1][j];
        nxt[i][s[i]-'a']=i;
    }
}
void solve(){
    scanf("%s%s",s1,s2);
    init(s1);
    int m=strlen(s2);
    scanf("%d",&q);
    while (q--){
        int l,r;
        scanf("%d%d",&l,&r);
        l--;r--;
        int ans=0;
        memset(dp,inf,sizeof(dp));//dp[i][j]代表与s2[1-i]公共子序列已经累计j个元素的最短前缀位置
        for (int i=0;i<m;i++)dp[i][1]=nxt[l][s2[i]-'a'];
        for (int i=1;i<m;i++){
            for (int j=1;j<=i+1;j++){
                dp[i][j]=min(dp[i][j],dp[i-1][j]);
                if (dp[i-1][j-1]<r)dp[i][j]=min(dp[i][j],nxt[dp[i-1][j-1]+1][s2[i]-'a']);
            }
        }
        for (int i=m;i>=1;i--){
            if (dp[m-1][i]<=r){
                ans=i;
                break;
            }
        }
        ans=r-l+1+m-ans*2;
        printf("%d\n",ans);
    }
}
int main() {
    int T;
    scanf("%d",&T);
    while (T--)solve();
    return 0;
}
posted @ 2020-07-24 10:24  Rynar  阅读(328)  评论(0)    收藏  举报