簡單的字串(回文子集數 二維線段樹)

2021-09-01 20:54:21 字數 1819 閱讀 6514

題目:

思路:第一步先處理如何計算乙個區間的回文子集個數

構成回文串,有兩種情況: 1. 每種字母都選偶數個,這樣一定可以構成回文串

2. 有一種字母選了奇數個,其他的選了偶數個,這樣也一定可以構成回文串

對於每種字母選偶數個或奇數個的選擇方法數,都可以用二項式定理得到2^(cnt-1)。那麼對應於第一種情況,答案應該是

所以最後答案應該是:

第二步就是考慮用二維線段樹去維護區間修改了:

意思就是維護對26個字母都建立一顆線段樹,每顆都取維護該字母在任意區間的數量,修改的時候注意方向。其他的和普通線段樹類似。

**:

#include using namespace std;

const int maxn=1e5+7;

typedef long long ll;

const int mod=1e9+7;

#define lson rt<<1

#define rson rt<<1|1

#define lson l,m,lson

#define rson m+1,r,rson

struct tree

tree[maxn<<2];

char a[maxn];

void push_up(int rt)

}void push_down(int rt)

for(int i=0;i<26;i++)

for(int i=0;i<26;i++)

for(int i=0;i<26;i++)

tree[lson].lazy+=t;

tree[rson].lazy+=t;

tree[rt].lazy=0;

}void build(int l,int r,int rt)

int m=(l+r)>>1;

build(lson);

build(rson);

push_up(rt);

}void updata(int l,int r,int v,int l,int r,int rt)

for(int i=0;i<26;i++)

tree[rt].lazy+=v;

tree[rt].lazy%=26;

return;

}push_down(rt);

int m=(l+r)>>1;

if(l<=m)

if(r>m)

push_up(rt);

}int query(int i,int l,int r,int l,int r,int rt)

push_down(rt);

int m=(l+r)>>1;

int ans=0;

if(l<=m)

if(r>m)

push_up(rt);

return ans;

}ll fac2[maxn];

int main()

int n,q;

scanf("%d%d",&n,&q);

scanf("%s",a+1);

build(1,n,1);

int op,l,r,v;

while(q--)

else

}for(int i=0;i<26;i++)

ans=ans*(cnt+1)%mod;

ans=(ans-1+mod)%mod;

printf("%d\n",ans);}}

return 0;

}

字串hash Matrix(二維)

給定乙個m行n列的01矩陣 只包含數字0或1的矩陣 再執行q次詢問,每次詢問給出乙個a行b列的01矩陣,求該矩陣是否在原矩陣 現過。第一行四個整數m,n,a,b。接下來乙個m行n列的01矩陣,數字之間沒有空格。接下來乙個整數q。接下來q個a行b列的01矩陣,數字之間沒有空格。對於每個詢問,輸出1表示...

二維陣列 字串 API

1 二維陣列 陣列中的元素,又指向乙個新的子陣列 何時使用 1.儲存橫行豎列的資料時 2.分組儲存上下級包含關係時 如何建立 1.先建立空陣列,再初始化元素為子陣列 var data data 0 0,0,0,0 data 1 0,0,0,0 何時使用 不確定子陣列的個數或內容時 2.建立時就初始化...

二維陣列 字元陣列與字串

要求 了解多維陣列的概念 掌握二維陣列的使用 掌握用字元陣列存放字串的方法 掌握字串的輸入及輸出方法 二維陣列的定義 例 int a 2 3 定義乙個二維陣列 該陣列有2行3列共6個元素 這6個元素都存放int型資料 儲存時先儲存第一行的3個元素,然後再儲存第二行的3個元素 可將此二維陣列看成是乙個...