• CF788E:New task


    n个数字中,每个数有数字A和属性B,每次操作将某个点x的属性B改变为0或1,求满足这样要求的子序列的个数:

    下标a<b<c<d<e,而Aa<=Ab=Ac=Ad>=Ae且Bb=Bc=Bd=1。

    区间操作,首推线段树!(然后就不会了,跑去看别人的代码)

    是这样的,重点在于中间那三个点,因为我们的修改操作只会影响修改的点的值的答案。

    直接维护一个这样的子序列不太容易,所以多维护Aa<=Ab和Aa<=Ab=Ac和Ac=Ad>=Ae和Ad>=Ae的序列,然后线段树up的时候才可以左右合并答案。

    大体思路就这样,由于线段树是要按照值来建的,也就是给每个值一棵线段树,为方便调值先离散化。

    Aa<=Ab和Ad>=Ae即每个点左边<=它和右边<=它的数,可以用树状数组预处理,详见代码。

    线段树中的信息用到“当前这棵子线段树的数的个数”size,以及上面提到的四个序列长度A,AB,BC,C,还有答案ABC。

    在线段树叶子节点只算A,C和size,其他数组慢慢合并,详见代码中up。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstring>
      6 //#include<iostream>
      7 using namespace std;
      8 
      9 int n;
     10 #define maxn 200011
     11 struct BIT
     12 {
     13     int a[maxn];
     14     void clear() {memset(a,0,sizeof(a));}
     15     int lowbit(int x) {return x&-x;}
     16     void add(int x,int v)
     17     {
     18         for (;x<=n;x+=lowbit(x)) a[x]+=v;
     19     }
     20     int query(int x)
     21     {
     22         int ans=0;
     23         for (;x;x-=lowbit(x)) ans+=a[x];
     24         return ans;
     25     }
     26 }bit;
     27 const int mod=1000000007;
     28 int Left[maxn],Right[maxn];
     29 #define maxs 2000011
     30 struct segmenttree
     31 {
     32     struct Node
     33     {
     34         int size,A,C,AB,BC,ABC;
     35         int son[2];
     36     }a[maxs];
     37     int size;
     38     segmenttree() {size=0;}
     39     void up(int x)
     40     {
     41         const int &p=a[x].son[0],&q=a[x].son[1];
     42         a[x].size=a[p].size+a[q].size;
     43         a[x].A=(a[p].A+a[q].A)%mod;
     44         a[x].C=(a[p].C+a[q].C)%mod;
     45         a[x].AB=(a[p].AB+a[q].AB+a[p].A*1ll*a[q].size)%mod;
     46         a[x].BC=(a[p].BC+a[q].BC+a[p].size*1ll*a[q].C)%mod;
     47         a[x].ABC=(a[p].ABC+a[q].ABC+1ll*a[p].A*a[q].BC+1ll*a[p].AB*a[q].C)%mod;
     48     }
     49     void modify(int &x,int L,int R,int id,int v)
     50     {
     51         if (!x) x=++size;
     52         if (L==R)
     53         {
     54             a[x].size=v*1;
     55             a[x].A=v*Left[id];
     56             a[x].C=v*Right[id];
     57             a[x].AB=a[x].BC=a[x].ABC=0;
     58             a[x].son[0]=a[x].son[1]=0;
     59         }
     60         else
     61         {
     62             const int mid=(L+R)>>1;
     63             if (id<=mid) modify(a[x].son[0],L,mid,id,v);
     64             else modify(a[x].son[1],mid+1,R,id,v);
     65             up(x);
     66         }
     67     }
     68 }seg;
     69 struct Point
     70 {
     71     int v,id;
     72     bool operator < (const Point &b) const {return v<b.v;}
     73 }b[maxn];
     74 int a[maxn],cnt=0;
     75 int root[maxn];
     76 int main()
     77 {
     78     scanf("%d",&n);
     79     for (int i=1;i<=n;i++) scanf("%d",&b[b[i].id=i].v);
     80     sort(b+1,b+1+n);
     81     a[b[1].id]=cnt=1;
     82     for (int i=2;i<=n;i++)
     83     {
     84         if (b[i].v!=b[i-1].v) cnt++;
     85         a[b[i].id]=cnt;
     86     }
     87     memset(Left,0,sizeof(Left));
     88     memset(Right,0,sizeof(Right));
     89     bit.clear();
     90     for (int i=1;i<=n;i++)
     91     {
     92         Left[i]=bit.query(a[i]);
     93         bit.add(a[i],1);
     94     }
     95     bit.clear();
     96     for (int i=n;i>=1;i--)
     97     {
     98         Right[i]=bit.query(a[i]);
     99         bit.add(a[i],1);
    100     }
    101     int ans=0;
    102     memset(root,0,sizeof(root));
    103     for (int i=1;i<=n;i++)
    104     {
    105         ans=(ans-seg.a[root[a[i]]].ABC+mod)%mod;
    106         seg.modify(root[a[i]],1,n,i,1);
    107         ans=(ans+seg.a[root[a[i]]].ABC)%mod;
    108     }
    109     int m,x,y;
    110     scanf("%d",&m);
    111     for (int i=1;i<=m;i++)
    112     {
    113         scanf("%d%d",&x,&y);
    114         ans=(ans-seg.a[root[a[y]]].ABC+mod)%mod;
    115         seg.modify(root[a[y]],1,n,y,x-1);
    116         ans=(ans+seg.a[root[a[y]]].ABC)%mod;
    117         printf("%d
    ",ans);
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    ==和equals
    instanceof和相关函数
    格式化输出
    [转]使用String的intern方法节省内存
    [转]请别再拿“String s = new String("xyz");创建了多少个String实例”来面试了吧
    Go编程语言学习笔记
    [javascript]什么是闭包?
    [javascript]彻底理解 JS 中 this 的指向
    constrained属性
    Python python 数据类型的相互转换
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7198150.html
Copyright © 2020-2023  润新知