• bzoj 4597||洛谷P4340 [Shoi2016]随机序列


    https://www.lydsy.com/JudgeOnline/problem.php?id=4597

    https://www.luogu.org/problemnew/show/P4340

    妄图直接暴力维护一堆东西,以直接维护题目要求的值(具体见代码...)

    最后花了2个小时维护完了,A掉了,然而好像常数比别人大一倍?

    上网搜题解,发现大部分东西都可以抵消掉??回想维护过程中,好像有一堆抵消掉的东西?

    看来即使可以暴力维护,也还是要多观察题目性质...

      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> pii;
     13 const ll md=1e9+7;
     14 ll n,q;
     15 ll a[100100];
     16 ll pw3[100100];
     17 const ll N=400100;
     18 #define lc (num<<1)
     19 #define rc (num<<1|1)
     20 ll d1[N],d2[N],d3[N],d4[N],d5[N];
     21 //d1:区间乘积
     22 //d2:区间和
     23 //d3:除了全部是乘号外,所有选择方案靠左边全是乘号一段的积的和
     24 //d4:除了全部是乘号外,...靠右边...(带符号)
     25 //d5:答案
     26 //维护过程中发现d4必定为0...
     27 /*
     28    举例:1,2,3
     29    1+2+3,1+2-3,1+2*3,
     30    1-2+3,1-2-3,1-2*3,
     31    1*2+3,1*2-3,1*2*3
     32    d3应当维护1*6+1*2*2=10
     33    d4应当维护3*3-3*3+2*3-2*3=0
     34 */
     35 void upd(ll l,ll r,ll num)
     36 {
     37     d1[num]=d1[lc]*d1[rc]%md;
     38     d2[num]=(d2[lc]+d2[rc])%md;
     39     ll mid=l+((r-l)>>1);
     40     d3[num]=(d3[lc]*pw3[r-mid]%md+d1[lc]*2*pw3[r-(mid+1)]%md
     41         +d1[lc]*d3[rc]%md)%md;
     42     d4[num]=(d4[rc]*pw3[mid-l+1]%md//+d1[rc]*2*pw3[mid-l]%md
     43         +d1[rc]*d4[lc]%md)%md;
     44     ll d4l=(d4[lc]+d1[lc])%md,d3r=(d3[rc]+d1[rc])%md;
     45     /*
     46     d5[num]=(2*(r-mid)*d5[lc]%md+(r-mid)*((d5[lc]-d4l+md)%md)%md
     47         +(mid-l+1)*((d5[rc]-d3r+md)%md)%md
     48         +d4l*d3r%md)%md;
     49     */
     50     ll m=pw3[mid-l],n=pw3[r-(mid+1)];
     51     /*
     52     d5[num]=(2*(r-mid)*d5[lc]%md+2*(mid-l+1)*d5[rc]%md
     53         +pw3[mid-l]*(md-2)%md*d3r%md
     54         +(r-mid)*((d5[lc]-d4l+md)%md)%md
     55         +(mid-l+1)*((d5[rc]-d3r+md)%md)%md
     56         +d4l*d3r%md)%md;
     57     */
     58     d5[num]=(2*n*d5[lc]%md+2*m*d5[rc]%md
     59         +m*(md-2)%md*d3r%md
     60         +n*((d5[lc]-d4l+md)%md)%md
     61         +m*((d5[rc]-d3r+md)%md)%md
     62         +d4l*d3r%md)%md;
     63 
     64     /*
     65     d5[num]=(2*(r-mid)*d5[lc]%md+2*(mid-l+1)*d5[rc]%md
     66         +pw3[mid-l]*(md-2)%md*d3r%md
     67         +(r-mid)*((d5[lc]-d4l+md)%md)%md
     68         +
     69     printf("1t%lld %lld %lld %lld %lld %lld %lld
    ",l,r,d1[num],d2[num],
     70         d3[num],d4[num],d5[num]);
     71     printf("2t%lld %lld %lld
    ",(r-mid)*d5[lc]%md+(mid-l+1)*d5[rc]%md,
     72         (r-mid)*d5[lc]%md+(mid-l+1)*d5[rc]%md+pw3[mid-l]*(md-2)%md*d3r%md,
     73         (r-mid)*((d5[lc]-d4l+md)%md)%md
     74         +(mid-l+1)*((d5[rc]-d3r+md)%md)%md
     75         +d4l*d3r%md);
     76     */
     77 }
     78 void pre(ll l,ll num,ll x)
     79 {
     80     d1[num]=x;
     81     d2[num]=x;
     82     d3[num]=d4[num]=0;
     83     d5[num]=x;
     84 }
     85 void build(ll l,ll r,ll num)
     86 {
     87     if(l==r)    {pre(l,num,a[l]);return;}
     88     ll mid=l+((r-l)>>1);
     89     build(l,mid,lc);build(mid+1,r,rc);
     90     upd(l,r,num);
     91 }
     92 void setx(ll L,ll x,ll l,ll r,ll num)
     93 {
     94     if(l==r)    {pre(l,num,x);return;}
     95     ll mid=l+((r-l)>>1);
     96     if(L<=mid)    setx(L,x,l,mid,lc);
     97     else    setx(L,x,mid+1,r,rc);
     98     upd(l,r,num);
     99 }
    100 int main()
    101 {
    102     ll i,x,y;
    103     pw3[0]=1;
    104     for(i=1;i<=100000;i++)
    105         pw3[i]=pw3[i-1]*3%md;
    106     scanf("%lld%lld",&n,&q);
    107     for(i=1;i<=n;i++)    scanf("%lld",&a[i]);
    108     build(1,n,1);
    109     //printf("%lld %lld %lld %lld %lld",d1[1],d2[1],d3[1],d4[1],d5[1]);
    110     while(q--)
    111     {
    112         scanf("%lld%lld",&x,&y);
    113         setx(x,y,1,n,1);
    114         printf("%lld
    ",d5[1]);
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    Contains Duplicate III
    Contains Duplicate
    bitmap
    机器人的运动范围
    矩阵中的路径
    不要62
    牛顿迭代法求方程的根
    统计C语言合法字符
    迭代法求平方根
    欧几里德算法(求两个正整数的最大公约数)
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9818590.html
Copyright © 2020-2023  润新知