1. 程式人生 > >{CodeForces】788E New task && 汕頭市隊賽SRM06 D 五色戰隊

{CodeForces】788E New task && 汕頭市隊賽SRM06 D 五色戰隊

sed 第一次 != 輸入 線段樹 urn sizeof codechef sum

D 五色戰隊 SRM 06

背景&&描述

遊行寺家裏人們的發色多種多樣,有基佬紫、原諒綠、少女粉、高級黑、相簿白等。 日向彼方:吾令人觀其氣,氣成五彩,此天子氣也。 琉璃:我們是不是可以組個五人戰隊了? 遊行寺家的n個人排成一排。第i個人的發色是Ai。 能組成戰隊的條件是: 那五人假設是第a,b,c,d,e人(技術分享),需要滿足 技術分享 中間的三人稱為有頭者,最旁邊倆人稱為學姐。 根據字面意思,有頭者一定要有頭,學姐可以無頭。
反正就是b,c,d這三人一定要有頭。 有著惡趣味的琉璃每次操作會把一個人 變成有頭或者無頭, 每次操作後琉璃想知道遊行寺家可能產生多少種不同的戰隊。只要有成員不同,倆戰隊就是不同的。

輸入格式

第一行一個整數n,第二行n個整數表示人們的發色。

第三行一個整數m,表示操作數。

接下來有m行,每行第一個數表示操作類型,第二個數表示被操作那人的編號。

類型為1就是把他變無頭,類型2就是變有頭。

輸出格式

每次操作後輸出答案,答案對10^9+7取模。。。

樣例輸入

8
3 4 4 2 4 5 4 1
3
1 5
2 5
1 2

樣例輸出

1
6
2

數據範圍與約定

  • 對於100%的數據:技術分享

樣例解釋

第一次操作後可能的戰隊為{1,2,3,7,8}

第二次操作後可能的戰隊為{1,2,3,5,7},{1,2,3,5,8},{1,2,3,7,8},{1,2,5,7,8},{1,3,5,7,8},{2,3,5,7,8}。

第三次操作後可能的戰隊為{1,3,5,7,8},{2,3,5,7,8}

這道題和codechef的原題差不多

題目要求的就是

n個數字中,每個數有數字A和屬性B,每次操作將某個點x的屬性B改變為0或1,求滿足這樣要求的子序列的個數:

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

那麽每個數左邊以及右邊小於等於他的數 很顯然我們可以用樹狀數組維護 下標就是值

當然為了方便我們需要將值離散化一波

這樣之後 重點就是中間那三個數了 我們可以按值來搞 每個值建一棵線段樹

需要維護的信息有(我們設五個點分別為 1 2 3 4 5

sz 及點的個數

A 就是 1 2

C 就是 2 3

AB就是 1 2 3

BC 就是 3 4 5

ABC 就是 1 2 3 4 5

具體怎麽算看up咯

跟結點只需要算A C 而A C可以由左邊比他小和右邊比他小的點的數量得到 這樣之後就簡單多了 2333

技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=2000007,N=200007,mod=1e9+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();}
    return ans*f;
}
int sum[N],s[N],ans;
struct node{int w,pos;}e[N];
bool cmp(node a,node b){return a.w<b.w;}
int n,m,cnt,sz;
int L[N],R[N],root[N];
void clear(){memset(sum,0,sizeof(sum));}
int lowbit(int x){return x&-x;}
void add(int x){
    while(x<=n){
        sum[x]++;
        x+=lowbit(x);
    }
}
int push_sum(int x){
    int ans=0;
    while(x){ans+=sum[x]; x-=lowbit(x);}
    return ans;
}
struct note{
    int l,r,sz;
    int A,C,AB,BC,ABC;
}tr[M];
void up(int x){
    int l=tr[x].l,r=tr[x].r;
    tr[x].sz=(tr[l].sz+tr[r].sz)%mod;
    tr[x].A=(tr[l].A+tr[r].A)%mod;
    tr[x].C=(tr[l].C+tr[r].C)%mod;
    tr[x].AB=(tr[l].AB+tr[r].AB+(LL)tr[l].A*tr[r].sz)%mod;
    tr[x].BC=(tr[l].BC+tr[r].BC+(LL)tr[r].C*tr[l].sz)%mod;
    tr[x].ABC=(tr[l].ABC+tr[r].ABC+(LL)tr[l].A*tr[r].BC+(LL)tr[l].AB*tr[r].C)%mod;
}
void mdf(int& x,int l,int r,int k,int v){
    if(!x) x=++sz;
    if(l==r){
        tr[x].sz=1*v;
        tr[x].A=L[k]*v;
        tr[x].C=R[k]*v;
        tr[x].AB=tr[x].BC=tr[x].ABC=0;
        tr[x].l=tr[x].r=0;
        return ;
    }
    int mid=(l+r)>>1;
    if(k<=mid) mdf(tr[x].l,l,mid,k,v);
    else mdf(tr[x].r,mid+1,r,k,v);
    up(x);
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++) e[i].w=read(),e[i].pos=i;
    sort(e+1,e+1+n,cmp);
    for(int i=1;i<=n;i++){
        if(e[i].w!=e[i-1].w) cnt++;
        s[e[i].pos]=cnt;
    }
    clear();
    for(int i=1;i<=n;i++){
        L[i]=push_sum(s[i]);
        add(s[i]);
    }
    clear();
    for(int i=n;i>=1;i--){
        R[i]=push_sum(s[i]);
        add(s[i]);
    }
    for(int i=1;i<=n;i++){
        ans=(ans-tr[root[s[i]]].ABC+mod)%mod;
        mdf(root[s[i]],1,n,i,1);
        ans=(ans+tr[root[s[i]]].ABC)%mod;
    }
    int x,y;
    m=read();
    for(int i=1;i<=m;i++){
        x=read(); y=read();
        ans=(ans-tr[root[s[y]]].ABC+mod)%mod;
        mdf(root[s[y]],1,n,y,x-1);
        ans=(ans+tr[root[s[y]]].ABC)%mod;
        printf("%d\n",ans);
    }
    return 0;
}
View Code

{CodeForces】788E New task && 汕頭市隊賽SRM06 D 五色戰隊