zoukankan      html  css  js  c++  java
  • HDU校赛 | 2019 Multi-University Training Contest 1

    2019 Multi-University Training Contest 1

    http://acm.hdu.edu.cn/contests/contest_show.php?cid=848

    1001. Blank

    这题我打比赛的时候想到正解了没敢写...

    (f_{a,b,c,d})表示({0,1,2,3}​)最后一次出现的位置排序之后的结果,那么每次枚举四种情况转移就好了。

    复杂度(O(Tn^4)),由于转移的循环除了个(4!)的常数所以跑的很快。

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    
    #define pii pair<int,int >
    #define vec vector<int >
    
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
    
    #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
    
    const int maxn = 1e6+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    const int mod = 998244353;
    
    int f[2][102][102][102],n,m,ans;
    vector<pii > s[102];
    
    void add(int &x,int y) {x+=y;if(x>=mod) x-=mod;}
    
    int check(int a,int b,int c,int d) {
        for(vector<pii > :: iterator i=s[a].begin();i!=s[a].end();i++)
            if((b>=i->fr)+(c>=i->fr)+(d>=i->fr)+1!=i->sc) return 0;
        return 1;
    }
    
    void solve() {
        read(n),read(m);
        for(int i=1,l,r,x;i<=m;i++) read(l),read(r),read(x),s[r].pb(mp(l,x));
        f[0][0][0][0]=1;
        for(int a=0,t=0;a<=n;a++,t^=1) {
            for(int b=0;b<=a+1;b++)
                for(int c=0;c<=b;c++)
                    for(int d=0;d<=c;d++)
                        f[t^1][b][c][d]=0;
            for(int b=0;b<(a?a:1);b++)
                for(int c=0;c<(b?b:1);c++)
                    for(int d=0;d<(c?c:1);d++) {
                        if(!check(a,b,c,d)) continue;
                        add(f[t^1][b][c][d],f[t][b][c][d]);
                        add(f[t^1][a][c][d],f[t][b][c][d]);
                        add(f[t^1][a][b][d],f[t][b][c][d]);
                        add(f[t^1][a][b][c],f[t][b][c][d]);
                        if(a==n) add(ans,f[t][b][c][d]);
                    }
        }
        write(ans);
    }
    
    void clear() {
        ans=0;
        memset(f,0,sizeof f);
        for(int i=1;i<=n;i++) s[i].clear();
    }
    
    int main() {
        int t;read(t);while(t--) solve(),clear();
        return 0;
    }
    

    1002. Operation

    赛后改的。。

    考虑记录前缀线性基,然后我们模仿单调队列,贪心的让每一位的位置尽可能的靠后。

    实现的话考虑对线性基每一位记录这一位最前出现的位置,这是因为这一位可能是很多数异或起来的,取最前面那个,实现可以参照代码。

    复杂度(O(Tnlog n))

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    
    #define pii pair<int,int >
    #define vec vector<int >
    
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
    
    #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
    
    const int maxn = 1e6+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    const int mod = 1e9+7;
    
    int v[maxn],n,a[maxn][31],p[maxn][31],m;
    
    void append(int x,int pos) {
        for(int i=30;~i;i--) a[pos][i]=a[pos-1][i],p[pos][i]=p[pos-1][i];
        int pps=pos;
        for(int i=30;~i;i--)
            if(x&(1<<i)) {
                if(!a[pps][i]) {a[pps][i]=x;p[pps][i]=pos;return ;}
                if(pos>p[pps][i]) swap(x,a[pps][i]),swap(pos,p[pps][i]);
                x^=a[pps][i];
            }
    }
    
    int query(int l,int r) {
        int ans=0;
        for(int i=30;~i;i--)
            if(p[r][i]>=l&&(ans^a[r][i])>ans) ans^=a[r][i];
        return ans;
    }
    
    void solve() {
        read(n),read(m);
        for(int i=1,x;i<=n;i++) read(x),append(x,i);
        int la=0;
        for(int i=1;i<=m;i++) {
            int op,l,r;read(op);
            if(op==0) {
                read(l),read(r);l=(l^la)%n+1,r=(r^la)%n+1;if(l>r) swap(l,r);
                write(la=query(l,r));
            } else {
                read(r);r=r^la;append(r,++n);
            }
        }
    }
    
    void clear() {
        for(int i=1;i<=n;i++) {
            memset(a[i],0,sizeof a[i]);
            memset(p[i],0,sizeof p[i]);
        }
    }
    
    int main() {
        int t;read(t);while(t--) solve(),clear();
        return 0;
    }
    

    1004. Vacation

    二分答案,然后从后往前枚举判断就好了。

    复杂度(O(Tnlog v))

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    
    #define pii pair<int,int >
    #define vec vector<int >
    
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
    
    #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
    
    const int maxn = 1e5+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    const int mod = 1e9+7;
    
    int n,l[maxn],s[maxn],v[maxn];
    
    int check(lf t) {
        lf lim=-1e9;
        for(int i=n;~i;i--) {
            lf tmp=(lf)s[i]-(lf)v[i]*t;
            if(tmp>lim) lim=tmp;
            lim+=l[i];
        }//printf("lim :: %.6lf
    ",lim);
        return lim-l[0]<=0;
    }
    
    void solve() {
        for(int i=0;i<=n;i++) read(l[i]);
        for(int i=0;i<=n;i++) read(s[i]);
        for(int i=0;i<=n;i++) read(v[i]);
        lf l=0,r=1e9;
        while(fabs(r-l)>1e-8) {
            lf mid=(l+r)*0.5;
            if(check(mid)) r=mid;
            else l=mid;
        }printf("%.8lf
    ",l);
    }
    
    int main() {
        while(scanf("%d",&n)!=EOF) solve();
        return 0;
    }
    

    1005. Path

    建出最短路径图,求最小割。

    代码挖坑。

    1012. Sequence

    首先我们把(a)写成生成函数(sum_{i=1}^{n}a_ix^i)

    对于一次(k)操作,显然(a)的生成函数会乘上(sum_{igeqslant 0}x^{ik})

    显然顺序不影响答案。

    那么统计一下每个操作出现了多少次,答案就是:

    [left(sum_{i=1}^{n}a_ix^i ight)cdotprod_{k=1}^3left(sum_{igeqslant 0}x^{ik} ight)^{cnt_k} ]

    注意到:

    [left(sum_{igeqslant 0}x^{ik} ight)^{t}=sum_{igeqslant 0}inom{i+t-1}{t-1}x^{ik} ]

    所以做三遍( m NTT)就可以了,复杂度(O(Tnlog n))

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    
    #define pii pair<int,int >
    #define vec vector<int >
    
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
    
    #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
    #define ll long long 
    
    const int maxn = 1e6+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    const int mod = 998244353;
    
    int n,m,a[maxn],t[4],b[maxn],N,bit,pos[maxn],w[maxn],mxn,fac[maxn],ifac[maxn];
    
    int qpow(int a,int x) {
        int res=1;
        for(;x;x>>=1,a=1ll*a*a%mod) if(x&1) res=1ll*res*a%mod;
        return res;
    }
    
    int add(int x,int y) {return x+y>=mod?x+y-mod:x+y;}
    int del(int x,int y) {return x-y<0?x-y+mod:x-y;}
    
    void prepare() {
        for(mxn=1,bit=0;mxn<=n*2;mxn<<=1,bit++);N=mxn;
        w[0]=1,w[1]=qpow(3,(mod-1)/mxn),fac[0]=ifac[0]=1;
        for(int i=2;i<=N;i++) w[i]=1ll*w[i-1]*w[1]%mod;
        for(int i=1;i<N;i++) pos[i]=pos[i>>1]>>1|((i&1)<<(bit-1));
        for(int i=1;i<m;i++) fac[i]=1ll*fac[i-1]*i%mod;
        for(int i=1;i<m;i++) ifac[i]=1ll*ifac[i-1]*qpow(i,mod-2)%mod;
    }
    
    void ntt(int *r,int op) {
        for(int i=1;i<N;i++) if(pos[i]>i) swap(r[i],r[pos[i]]);
        for(int i=1,d=mxn>>1;i<N;i<<=1,d>>=1)
            for(int j=0;j<N;j+=i<<1)
                for(int k=0;k<i;k++) {
                    int x=r[j+k],y=1ll*r[i+j+k]*w[k*d]%mod;
                    r[j+k]=add(x,y),r[i+j+k]=del(x,y);
                }
        if(op==-1) {
            reverse(r+1,r+N);int d=qpow(N,mod-2);
            for(int i=0;i<N;i++) r[i]=1ll*r[i]*d%mod;
        }
    }
    
    int c(int a,int b) {return 1ll*fac[a]*ifac[b]%mod*ifac[a-b]%mod;}
    
    void calc(int k) {
        for(int i=0;i<N;i++) b[i]=0;
        b[0]=1;
        for(int i=1;i*k<=n;i++) b[i*k]=c(i+t[k]-1,t[k]-1);
        ntt(a,1),ntt(b,1);
        for(int i=0;i<N;i++) a[i]=1ll*a[i]*b[i]%mod;
        ntt(a,-1);
        for(int i=n+1;i<N;i++) a[i]=0;
    }
    
    void solve() {
        read(n),read(m);prepare();
        for(int i=1;i<=n;i++) read(a[i]);
        for(int i=1,x;i<=m;i++) read(x),t[x]++;
        for(int i=1;i<=3;i++) calc(i);ll ans=0;
        for(int i=1;i<=n;i++) ans^=1ll*i*a[i];
        printf("%lld
    ",ans);
    }
    
    void clear() {
        t[1]=t[2]=t[3]=0;
        for(int i=0;i<N;i++) a[i]=b[i]=0;
    }
    
    int main() {
        int t;read(t);while(t--) solve(),clear();
        return 0;
    }
    
  • 相关阅读:
    浅谈MIPS地址对齐问题
    一些使用的linux库
    linux curl网络库的使用方法
    一些json在js和c++ jsoncpp的操作
    Java开发小技巧(六):使用Apache POI读取Excel
    Java开发小技巧(五):HttpClient工具类
    vue-router 组件复用问题
    Vuejs之开发环境搭建
    Java开发小技巧(四):配置文件敏感信息处理
    Java开发小技巧(三):Maven多工程依赖项目
  • 原文地址:https://www.cnblogs.com/hbyer/p/11270779.html
Copyright © 2011-2022 走看看