zoukankan      html  css  js  c++  java
  • Wannafly挑战赛19

    Wannafly挑战赛19


    A. 队列Q

    需要支持把一个元素移到队首,把一个元素移到队尾,移到队首就直接放到队首前面那个位置,原位置标为0,队尾同理。

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    typedef long long ll;
    const int N = 30000200;
    using namespace std;
    int n,m;
    int q[N],hd,x,ed,P[N];
    char s[1111];
    void F(int x) {
        int p = P[x];
        swap(q[p],q[hd]);
        P[x] = hd;
        hd--;
    }
    void L(int x){
        int p=P[x];
        swap(q[p],q[ed]);
        P[x]=ed;
        ed++;
    }
    int main() {
        scanf("%d",&n);
        hd = 500000;
        ed = hd + n - 1;
        rep(i,hd,ed)scanf("%d",&q[i]),P[q[i]]=i;
        hd--;ed++;
        scanf("%d",&m);
        rep(ti,1,m){
            scanf(" %s %d",s,&x);
            if(s[0]=='F'){
                F(x);
            }
            else {
                L(x);
            }
        }
        int f=0;
        rep(i,hd,ed)if(q[i]){
            if(f)printf(" ");f=1;
            printf("%d",q[i]);
        }puts("");
        return 0;
    }
    
    

    B. 矩阵

    带限制的最大子矩阵,首先是与不带限制的最大子矩阵一样,最上边的边和底边,然后做最大子段和。带上了0的限制和长度限制,于是写了个双指针,就过了。(讲道理感觉双指针有点假。。。
    ps: 好像真的是假算法,回头补下单调栈做法。

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    typedef long long ll;
    const int N = 555;
    const ll inf = 1000000000000000LL;
    using namespace std;
    int R,C,X,Y,Z;
    ll mp[N][N], sum[N][N], sum0[N][N], a[N], b[N];
    int ck(int l,int r,ll x,ll y) {
        if(r-l+1 <= Y && l<=r && r<=C && x<=Z) return 1;
        return 0;
    }
    ll solve() {
        ll res=0,ans=a[1],ans0=b[1];
        rep(i,1,C)res=max(res,a[i]);
        int l = 1, r = 1;
        while(l<=r&&r<=C) {
            if(ck(l,r,ans0,ans))res = max(res,ans);
            while(ck(l,r+1,ans0+b[r+1],ans))++r,ans+=a[r],ans0+=b[r],res=max(res,ans);
            if(ck(l,r,ans0,ans))res = max(res,ans);
            ans -= a[l];
            ans0 -= b[l];
            ++l;
            while(a[l]<=0&&l<=C)ans0-=b[l],ans-=a[l],++l;
            while(l>r)++r,ans0+=b[r],ans+=a[r];
            if(ck(l,r,ans0,ans))res = max(res,ans);
        }
        return res;
    }
    int main() {
        scanf("%d %d %d %d %d",&R,&C,&X,&Y,&Z);
        rep(i,1,R)rep(j,1,C)scanf("%lld",&mp[i][j]);
    
        rep(i,1,R)rep(j,1,C){
            sum[i][j] = sum[i-1][j] + mp[i][j];
            if(mp[i][j]==0) sum0[i][j] = sum0[i-1][j] + 1;
            else sum0[i][j] = sum0[i-1][j];
        }
        ll ans = 0;
        rep(l,1,R)rep(r,l,min(R,l+X-1)){
            rep(k,1,C) a[k] = sum[r][k]-sum[l-1][k], b[k] = sum0[r][k]-sum0[l-1][k];
            ans = max(ans,solve());
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
    

    C. 多彩的树

    预处理每种颜色状态下的路径数,但是这次统计的包含这个状态的所有子状态。因此考虑容斥,当当前状态的颜色数为奇数时,加奇数,减偶数,当为偶数时加偶数减奇数。
    (eg1: a1a2 = (a1a2 + a1 + a2) - a1 - a2)
    (eg2: a1a2a3 = (a1a2a3 + a1a2 + a2a3 + a1a3 + a1 + a2 + a3) - (a1a2 + a1 + a2) - (a2a3 + a2 + a3) - (a1a3 + a1 + a3) + a1 + a2 + a3)
    没有系统学习过容斥,碰见类似容斥,最好举几个例子找规律

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    typedef long long ll;
    const int N = 50004;
    const ll mod = 1e9 + 7;
    using namespace std;
    struct edge{int e,nxt;}E[N<<1];
    int h[N],cc;
    void add(int u,int v) {
        E[cc].e = v;E[cc].nxt = h[u];h[u]=cc;++cc;
    }
    int n,k,x,y,a[N],col[12],vis[N],cnt[1<<11];
    ll ans[12],dp[(1<<12)],num[(1<<12)];
    ll dfs(int s) {
        ll res = 1;
        vis[s] = 1;
        for(int i=h[s];~i;i=E[i].nxt) {
            int v = E[i].e;
            if(!vis[v]&&col[a[v]]) {
                res += dfs(v);
            }
        }
        return res;
    }
    int main() {
        scanf("%d%d",&n,&k);
        rep(i,1,n) scanf("%d",&a[i]);
        memset(h,-1,sizeof(h));
        rep(i,1,n-1)scanf("%d%d",&x,&y),add(x,y),add(y,x);
    
        rep(i,1,(1<<k)-1) {
            dp[i]=cnt[i]=0;
            rep(j,0,k-1){
                col[j+1]=0;
                if(i&(1<<j))col[j+1]=1,++cnt[i];
            }
            rep(j,1,n)vis[j]=0;
            rep(j,1,n)if(!vis[j]&&col[a[j]]){
                ll tmp = dfs(j);
                dp[i] += tmp*(tmp-1)/2;
                dp[i]%=mod;
            }
        }
    
        rep(i,1,(1<<k)-1){num[i]=0;
            for(int j=i;j>0;--j)if((j|i)==i){
                if((cnt[i]-cnt[j])&1)
                    num[i]-=dp[j];
                else
                    num[i]+=dp[j];
                num[i]%=mod;num[i]+=mod;num[i]%=mod;
            }
            ans[cnt[i]] += num[i]; ans[cnt[i]]%=mod;
        }
        ans[1]+=n;ans[1]%=mod;
        ll res = 0;
        for(int i = k; i >= 0; --i) {
            res = ((res*131LL%mod + ans[i]%mod)%mod)%mod;
        }
        printf("%lld
    ",res);
        return 0;
    }
    
    
  • 相关阅读:
    Servlet基本用法(一)基本配置
    python 起航第一步吧
    shell脚本的执行方式
    linux 计划任务执行命令 crontab -e
    一个完整的 curl post登录带验证码的代码
    php curl post登录与带cookie模拟登录随笔
    liunx 配置 php curl 拓展库的方法
    php 魔术方法学习笔记
    php curl选项列表(超详细)
    正则表达式后面接的/isU, /is, /s含义
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9275919.html
Copyright © 2011-2022 走看看