題目:
思路:第一步先處理如何計算乙個區間的回文子集個數
構成回文串,有兩種情況: 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個元素 可將此二維陣列看成是乙個...