zoukankan      html  css  js  c++  java
  • Curious Array Codeforces

    https://codeforces.com/problemset/problem/407/C

    (自用,勿看)

    手模一下找一找规律,可以发现,对于一个修改(l,r,k),相当于在[l,r]内各位分别加上[1,0,0,0,0,..]做k+1次前缀和得到的数组

    比如(l=3,r=6,k=2),[1,0,0,..]做k+1=3次前缀和后为[1,3,6,10,15,..],因此这次修改相当于a[l]+=1,a[l+1]+=3,a[l+2]+=6,a[l+3]+=10

    很容易想到k从大到小排序,用差分维护,不断做前缀和“解包”(不展开写了..)

    然后我就不会了。。因为每一次是“区间加”,我只能做到从某个位置到末尾全部加,没有办法把多余的消掉

    膜了大佬,发现只要每一层差分的时候都在合适位置减去合适值就行了,找规律(例如l=3,r=6,k=2,一开始是1,0,0,0,-1,第一次变成1,1,1,1,0,再变成1,1,1,1,-4,第二次变成1,2,3,4,0,再变成1,2,3,4,-10,第三次变成1,3,6,10,0)(考虑第p次,[1,0,0,0..]做p+1次前缀和得到数组c,那么在r+1位置处减去c[r-l+1],第0次(即第1次开始前)也要减)

    然后多个同一阶的差分数列可以直接相加,因此就有了O((n+m)k)的做法

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 #define fi first
     7 #define se second
     8 #define mp make_pair
     9 #define pb push_back
    10 typedef long long ll;
    11 typedef unsigned long long ull;
    12 typedef pair<ll,ll> pll;
    13 const ll md=1000000007;
    14 ll n,m;
    15 vector<pll> a1[102];
    16 ll an[102][100100];
    17 ll tt[102][100100];//tt[i]是对1,0,0,0,..做i+1次前缀和得到的数组
    18 ll a[100100];
    19 int main()
    20 {
    21     ll i,j,k,x,y,z;pll t;
    22     scanf("%lld%lld",&n,&m);
    23     for(i=1;i<=n;i++)
    24         scanf("%lld",&a[i]);
    25     for(i=1;i<=n;i++)
    26         tt[0][i]=1;
    27     for(i=1;i<=100;i++)
    28     {
    29         for(j=1;j<=n;j++)
    30         {
    31             tt[i][j]=(tt[i][j-1]+tt[i-1][j]);
    32             (tt[i][j]>=md) && (tt[i][j]-=md);
    33             //printf("at%lld %lld %lld
    ",i,j,tt[i][j]);
    34         }
    35     }
    36     for(i=1;i<=m;i++)
    37     {
    38         scanf("%lld%lld%lld",&x,&y,&z);
    39         a1[z].pb(mp(x,y));
    40     }
    41     for(i=100;i>=0;i--)
    42     {
    43         for(j=0;j<a1[i].size();j++)
    44         {
    45             x=a1[i][j].fi;y=a1[i][j].se;
    46             ++an[i][x];
    47             (an[i][x]>=md) && (an[i][x]-=md);
    48             ++y;
    49             for(k=i;k>=0;k--)
    50             {
    51                 an[k][y]-=tt[i-k][y-x];
    52                 //printf("2t%lld %lld %lld
    ",i-k,y-x,tt[i-k][y-x]);
    53                 //printf("1t%lld %lld %lld
    ",k,y,tt[i-k][y-x]);
    54                 (an[k][y]<0) && (an[k][y]+=md);
    55             }
    56         }
    57         for(k=1;k<=n;k++)
    58         {
    59             an[i][k]+=an[i][k-1];
    60             (an[i][k]>=md) && (an[i][k]-=md);
    61         }
    62         if(i!=0)
    63         {
    64             for(k=1;k<=n;k++)
    65             {
    66                 an[i-1][k]+=an[i][k];
    67                 (an[i-1][k]>=md) && (an[i-1][k]-=md);
    68             }
    69         }
    70         //printf("1t%lld
    ",i);
    71         //for(k=1;k<=n;k++)
    72         //    printf("%lld ",an[i][k]);
    73         //puts("");
    74     }
    75     for(i=1;i<=n;i++)
    76     {
    77         a[i]+=an[0][i];
    78         (a[i]>=md) && (a[i]-=md);
    79     }
    80     for(i=1;i<=n;i++)
    81         printf("%lld ",a[i]);
    82     return 0;
    83 }
    View Code

    http://210.33.19.103/contest/1025

    A题(sequence)同此题

  • 相关阅读:
    微信公众号菜单demo
    Hosts 广告
    thinkphp用swiftmailer发邮件demo
    微信小程序小结(4) -- 分包加载及小程序间跳转
    微信小程序小结(5) -- 常用语法
    常用SQL语句及在node中使用MySQL
    JavaScript -- tips
    CSS3 -- FlexBox(弹性盒子)
    gulp使用文档
    yarn快速使用及实践建议
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9836987.html
Copyright © 2011-2022 走看看