zoukankan      html  css  js  c++  java
  • dtoi4699 序列

    题意:

         已知大小为n的一个排列,对于任意一个子序列s,它对ans[k]的贡献为(对于任意的i<|s|,满足s[i]>k>s[i+1]或者s[i]<k<s[i+1]的i的数量)。输出ans[k],k∈[1,n]

    题解:

         由于个人比较菜,所以我的方法很奇怪。

         从小到大枚举i,考虑每一次“点亮”它所在的位置,那么当前的答案就是所有“亮”的位置和“不亮”的位置的贡献。

         对于一组合法的(i,j),它对答案的贡献就是2^(n-(j-i+1))。

         那么我有一个位置亮了起来,它对答案就会新增暗的地方对它的贡献,所以说我们就用总的贡献减去亮的地方对它的贡献,那么亮的地方对它的贡献可以用线段树维护。大概就是维护一个等比数列,因为等比数列+等比数列还是等比数列,当然比要相等,本题中比只会有2或1/2,所以可以使用线段树维护。

         然而本题空间5M(不知道出题人想干啥),于是我就把原本正常的代码各种乱改,以时间换空间甚至是小范围分块大范围快速幂求a^b。然后卡着1s过去了。

    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    const int mod=1e9+7;
    int n,a,t[100002],d,ans,cf[30002];
    typedef struct{
        int sx1,sc1,sx2,sc2;
    }P;
    P p[300002];
    inline long long ccj(long long x,long long y){
        if (x==2 && y<=100000)
        {
            int ans=1;
            if (y<=30000)return cf[y];
            while(y>=30000)
            {
                ans=(long long)ans*cf[30000]%mod;y-=30000;
            }
            ans=(long long)ans*cf[y]%mod;
            return ans;
        }
        int ans=1;
        while(y)
        {
            if (y&1)ans=ans*x%mod;
            x=x*x%mod;y>>=1;
        }
        return ans;
    }
    inline void gengxin1(int root,int begin,int end,int begin2,int end2,int sx,bool u){
        if (begin>end2 || end<begin2)return;
        if (begin>=begin2 && end<=end2)
        {
            if (u)
            {
                p[root].sx1=(p[root].sx1+(long long)sx*ccj(2,begin-begin2)%mod)%mod;
            }
            else
            {
                p[root].sc1=(p[root].sc1+(long long)sx*ccj(ccj(2,begin-begin2)%mod,mod-2))%mod;
            }
            return;
        }
        int mid=(begin+end)/2;
        gengxin1(root*2,begin,mid,begin2,end2,sx,u);gengxin1(root*2+1,mid+1,end,begin2,end2,sx,u);
    }
    inline void gengxin2(int root,int begin,int end,int begin2,int end2,int sx,bool u){
        if (begin>end2 || end<begin2)return;
        if (begin>=begin2 && end<=end2)
        {
            if (u)
            {
                p[root].sx2=(p[root].sx2+(long long)sx*ccj(2,begin-begin2)%mod)%mod;
            }
            else
            {
                p[root].sc2=(p[root].sc2+(long long)sx*ccj(ccj(2,begin-begin2)%mod,mod-2)%mod)%mod;
            }
            return;
        }
        int mid=(begin+end)/2;
        gengxin2(root*2,begin,mid,begin2,end2,sx,u);gengxin2(root*2+1,mid+1,end,begin2,end2,sx,u);
    }
    inline void chaxun1(int root,int begin,int end,int wz){
        ans=(ans-ccj(2,wz-begin)*p[root].sx1%mod)%mod;
        ans=(ans-ccj(ccj(2,wz-begin),mod-2)*p[root].sc1%mod)%mod;
        ans=(ans+mod)%mod;
        if (begin==end)return;
        int mid=(begin+end)/2;
        if (wz<=mid)chaxun1(root*2,begin,mid,wz);
        else chaxun1(root*2+1,mid+1,end,wz);
    }
    inline void chaxun2(int root,int begin,int end,int wz){
        ans=(ans-ccj(2,wz-begin)*p[root].sx2%mod)%mod;
        ans=(ans-ccj(ccj(2,wz-begin),mod-2)*p[root].sc2%mod)%mod;
        ans=(ans+mod)%mod;
        if (begin==end)return;
        int mid=(begin+end)/2;
        if (wz<=mid)chaxun2(root*2,begin,mid,wz);
        else chaxun2(root*2+1,mid+1,end,wz);
    }
    int main()
    {
        scanf("%d",&n);cf[0]=1;
        for (int i=1;i<=30000;i++)cf[i]=cf[i-1]*2%mod;
        for (int i=1;i<=n;i++){scanf("%d",&a);t[a]=i;}
        for (int i=1;i<=n;i++)
        {
            chaxun2(1,1,n,t[i]);
            printf("%lld
    ",ans);d=0;
            int t1=ccj(2,n-2),t2=ccj(2,n-t[i]),t3=ccj(2,n-t[i]);
            if (t[i]<n)
            {
                gengxin1(1,1,n,t[i]+1,n,t1,0);
                gengxin2(1,1,n,t[i]+1,n,t1,0);
                d=((t1*2%mod-1)-ccj(2,t[i]-1)+1)%mod;
                d=(d%mod+mod)%mod;
            }
            if (t[i]>1)
            {
                gengxin1(1,1,n,1,t[i]-1,t3,1);
                gengxin2(1,1,n,1,t[i]-1,t3,1);
                d=(d+(t1*2%mod-1)-t2+1)%mod;
                d=(d%mod+mod)%mod;
            }
            ans=(ans+d)%mod;chaxun1(1,1,n,t[i]);
        }
        return 0;
    }
  • 相关阅读:
    CSS躬行记(9)——网格布局
    CSS躬行记(8)——裁剪和遮罩
    CSS躬行记(7)——合成
    CentOS 系统目录解析
    Linux 命令快捷键
    秒的精确度
    Oracle和mysql中装逼dual表的用途介绍
    mysql 的mgr集群
    ansible笔记
    cygwin
  • 原文地址:https://www.cnblogs.com/1124828077ccj/p/12261930.html
Copyright © 2011-2022 走看看