zoukankan      html  css  js  c++  java
  • 牛客NOIP暑期七天营-提高组3

    -----------今天是被打爆的一天,T3就是用正解做的,但是好像zz了,只得了30分。-----------------

    ----------------   T1由于没判不合法的情况,也只有15分---------------------

     ---------------------果然是一个拿不到noip一等奖的人----------------------------

    ----------------------------毕竟noip都准备改名了?-------------------------

    A:破碎的矩阵。

    题意:给出N,M,表示有N*M的矩阵,然后给定每一行的异或和,每一列的异或和,求方案数。

    思路:如果合法,方案数是pow(2,(N-1)*(M-1)),这个很好想,因为你确定了一个N*M的左上方(N-1)*(M-1)的矩阵后,最后一行一列可以反推,是唯一的。 不合法的情况是,异或和不为0;

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=2000010;
    int ans,N,M,Mod; ll x,a[maxn],b[maxn];
    int qpow(int base,int num)
    {
        int res=1; while(num){
            if(num&1) res=1LL*res*base%Mod;
            num>>=1; base=1LL*base*base%Mod;
        }return res;
    }
    void solve(int t)
    {
        int res=qpow(qpow(qpow(2,N-1),M-1),t);
        ans=1LL*res%Mod%Mod;
    }
    int main()
    {
        int T; scanf("%d",&T);
        while(T--){
            ll xxx=0;
            scanf("%d%d%lld%d",&N,&M,&x,&Mod);
            rep(i,1,N) scanf("%lld",&a[i]),xxx^=a[i];
            rep(i,1,M) scanf("%lld",&b[i]),xxx^=b[i];
            if(xxx) puts("0");
            else {
               int t=0;
               rep(i,0,60) if(x&(1LL<<i)) t++;
               solve(t);
               printf("%d
    ",ans);
            }
        }
        return 0;
    }
    View Code

    B:点与面。

    题意:求W的个数。

    思路:裸题,三次BIT即可。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=500010;
    const int Mod=998244353;
    int a[maxn],b[maxn],tot;
    ll L[maxn],R[maxn],ans,sum[maxn],res[maxn];
    ll query(int x){ int res=0;while(x){ (res+=sum[x])%=Mod; x-=(-x)&x;} return res;}
    void add(int x,ll y){ while(x<=tot){ sum[x]+=y; if(sum[x]>=Mod) sum[x]-=Mod; x+=(-x)&x;} }
    int main()
    {
        int N; scanf("%d",&N);
        rep(i,1,N) scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+N+1);  tot=unique(b+1,b+N+1)-(b+1);
        rep(i,1,N) a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
        rep(i,1,N) L[i]=i-1-query(a[i]),add(a[i],1);
    
        rep(i,1,tot) sum[i]=0;
        for(int i=N;i>=1;i--) R[i]=N-i-query(a[i]),add(a[i],1);
    
        rep(i,1,tot) sum[i]=0;
        rep(i,1,N) res[i]=1;
        rep(i,1,N) (res[i]*=query(a[i]-1))%=Mod,add(a[i],L[i]);
    
        rep(i,1,tot) sum[i]=0;
        for(int i=N;i>=1;i--) (res[i]*=query(a[i]-1))%=Mod,add(a[i],R[i]);
    
        rep(i,1,N) ans+=res[i];
        printf("%lld
    ",ans%Mod);
        return 0;
    }
    View Code

    C:信息传递

    题意: Venn的班级有n个人,他们的座位是首尾相连呈环形的。
    如果第i个人得到了Venn的雀魂消息,下一秒就会告诉他左边的Li个人,和右边的Ri个人
    注意:由于他们是一个环形,第1个人的左边一个人是第n个人,第n个人的右边一个人是第1个人。
    Venn为了防止自己掉分的惨案被大家知道,他想知道对于每一个人,如果消息从他这里传播,需要多久整个班级就会知道。

    思路:一眼就可以想到做法,由于ans会比较大,所以倍增。 dp[i][j]表示从i出发,经过1<<j妙,最左到哪里,dp[i][j]=min(L[dp[i][j-1]]...L[i]),区间更新, 所以每一层用线段树优化。

    但是我只得了30分。 是因为有个wa点。 就是可能消息不是单方向传递的,所以左右转移要同时进行。 比如1先向右传递到2号学生,2号学生的Li非常的小,那么消息就传到很左边了。

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define f first
    #define s second
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=300010;
    const int inf=1e9;
    int l[maxn],r[maxn],a[maxn][18],b[maxn][18],Mn[maxn<<2][18],Mx[maxn<<2][18];
    void build(int Now,int L,int R,int p)
    {
        if(L==R) {
            Mx[Now][p]=b[L][p];
            Mn[Now][p]=a[L][p];
            return ;
        }
        int Mid=(L+R)>>1;
        build(Now<<1,L,Mid,p);
        build(Now<<1|1,Mid+1,R,p);
        Mx[Now][p]=max(Mx[Now<<1][p],Mx[Now<<1|1][p]);
        Mn[Now][p]=min(Mn[Now<<1][p],Mn[Now<<1|1][p]);
    }
    pii query(int Now,int L,int R,int l,int r,int p)
    {
        if(l<=L&&r>=R) return pii{ Mx[Now][p],Mn[Now][p]};
        int Mid=(L+R)>>1; pii res,tmp;
        res.f=-inf,res.s=inf;
        if(l<=Mid) {
            tmp=query(Now<<1,L,Mid,l,r,p);
            res.f=max(res.f,tmp.f);
            res.s=min(res.s,tmp.s);
        }
        if(r>Mid) {
            tmp=query(Now<<1|1,Mid+1,R,l,r,p);
            res.f=max(res.f,tmp.f);
            res.s=min(res.s,tmp.s);
        }
        return res;
    }
    int main()
    {
        int N,M; scanf("%d",&N); M=3*N;
        rep(i,1,N) scanf("%d",&l[i]),l[i+N]=l[i+N+N]=l[i];
        rep(i,1,N) scanf("%d",&r[i]),r[i+N]=r[i+N+N]=r[i];
        if(N==1){
            puts("0");
            return 0;
        }
        rep(i,1,M) a[i][0]=max(1,i-l[i]);
        rep(i,1,M) b[i][0]=min(M,i+r[i]);
        build(1,1,M,0);
        rep(j,1,17) {
            rep(i,1,M){
                pii t=query(1,1,M,a[i][j-1],b[i][j-1],j-1);
                b[i][j]=t.f;
                a[i][j]=t.s;
            }
            build(1,1,M,j);
        }
        rep(i,1,N) {
            int res=0,L=N+i,R=N+i;
            for(int j=17;j>=0;j--){
                pii t=query(1,1,M,L,R,j);
                int tL=t.s,tR=t.f;
                if(tR-tL<N-1) R=tR,L=tL,res+=(1<<j);
            }
            printf("%d ",res+1);
        }
        return 0;
    }
  • 相关阅读:
    Celery最佳实践(转)
    我希望知道的关于Django的11件事(转)
    Celery和Rabbitmq自学
    我眼中的各种编程语言(转)
    linux 的nohup & 和daemon 总结(转)
    模糊测试之AVI文件分析
    微信Netting-QRLJacking分析利用-扫我二维码获取你的账号权限
    一个Unix内核级别漏洞(一)
    一次对SNMP服务的渗透测试
    定位日站大法之-社会工程学
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11390312.html
Copyright © 2011-2022 走看看