题目传送门

题意:

这个题目真的是最近遇到的最难读。

有一个长度n的字符串,每一位字符都代表的是该种种类的敌人。

现在如果一个序列合法的话,就是同一种种类的敌人都在字符串的左半边或者右半边。

现在有q次询问,现在问你将 s[x] 和 s[y] 的敌人都放在同一边的合法方案数是多少。

题解:

首先如果划分组之后,那么答案就是,m! * m! * 2/ (c1! * c2! * c3! .... )

然后对于每一组来说就是 这个值是一定的。

然后就是需要求这个分组方案数。

对于分组方案数,可以通过背包来求这个方案数是多少。

但是如果枚举每个同类的字符,那么最后的复杂度是52 * 52 * 52 * n。

所以可以将总方案数先算出来,然后再将x,y的方案数,从里面删除,删除之后,不含x,y的方案数,相当于含了x,y的方案数。 这个复杂度是52*52*n。

代码:

/*
code by: zstu wxk
time: 2019/02/07
*/
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
int cnt[N];
char s[N];
LL ans[][];
int F[N], Finv[N], inv[N];/// F是阶层 Finv是逆元的阶层
void init(){
inv[] = ;
for(int i = ; i < N; i++)
inv[i] = (mod - mod/i) * 1ll * inv[mod % i] % mod;
F[] = Finv[] = ;
for(int i = ; i < N; i++){
F[i] = F[i-] * 1ll * i % mod;
Finv[i] = Finv[i-] * 1ll * inv[i] % mod;
}
}
int comb(int n, int m){ /// C(n,m)
if(m < || m > n) return ;
return F[n] * 1ll * Finv[n-m] % mod * Finv[m] % mod;
}
int id(char ch){
if(islower(ch)) return ch - 'a' + ;
return ch - 'A' + ;
}
int dp[N], tp[N];
void Ac(){
int n = strlen(s+);
int m = n / ;
for(int i = ; i <= n; ++i)
++cnt[id(s[i])];
dp[] = ;
for(int i = ; i <= ; ++i){
if(cnt[i]){
for(int j = m; j >= cnt[i]; --j)
dp[j] = (dp[j] + dp[j-cnt[i]]) % mod;
}
}
for(int i = ; i <= m; ++i)
tp[i] = dp[i];
for(int i = ; i <= ; ++i){
if(cnt[i] && cnt[i] <= m){
for(int j = cnt[i]; j <= m; ++j){
dp[j] = (dp[j] - dp[j-cnt[i]] + mod) % mod;
}
ans[i][i] = dp[m];
for(int j = ; j <= ; ++j){
if(cnt[j] && cnt[j] <= m && j != i){
for(int k = cnt[j]; k <= m; ++k){
dp[k] = (dp[k] - dp[k-cnt[j]] + mod)%mod;
}
ans[i][j] = dp[m];
for(int k = m; k >= cnt[j]; --k){
dp[k] = (dp[k] + dp[k-cnt[j]]) % mod;
}
}
}
for(int j = m; j >= cnt[i]; --j)
dp[j] = tp[j];
}
}
LL zz = 2ll * F[m] * F[m] % mod;
for(int i = ; i <= ; ++i)
zz = (zz * Finv[cnt[i]]) % mod;
int q, x, y;
scanf("%d", &q);
while(q--){
scanf("%d%d", &x, &y);
printf("%I64d\n", zz * ans[id(s[x])][id(s[y])] % mod);
}
return ;
}
int main(){
init();
while(~scanf("%s", s+)){
Ac();
}
return ;
}

CF - 1111D Destroy the Colony DP的更多相关文章

  1. Codeforces 1111D Destroy the Colony 退背包 (看题解)

    第一次知道这种背包还能退的.... 我们用dp[ i ]表示选取若干个物品重量到达 i 的方案数. 如果我们g[ i ]表示不用第 x 个物品的, 然后选若干其他的物品到达 i 的方案数. if(i ...

  2. Codeforces1111D Destroy the Colony 退背包+组合数

    Codeforces1111D 退背包+组合数 D. Destroy the Colony Description: There is a colony of villains with severa ...

  3. CF 983B XOR-pyramid(区间dp,异或)

    CF 983B XOR-pyramid(区间dp,异或) 若有一个长度为m的数组b,定义函数f为: \(f(b) = \begin{cases} b[1] & \quad \text{if } ...

  4. Destroy the Colony CodeForces - 1111D (可逆背包,计数)

    大意:给定字符串$s$, 保证长度为偶数, 给定q个询问, 每次询问给定两个位置$x$,$y$, 可以任意交换字符, 要求所有字符$s[x],s[y]$在同一半边, 剩余所有同种字符在同一半边的方案数 ...

  5. CF 9D. How many trees?(dp)

    题目链接 以前做过类似的,USACO,2.3,开始数组开小了,导致数据乱了,然后超数据范围了,.. #include <cstdio> #include <iostream> ...

  6. CF 346B. Lucky Common Subsequence(DP+KMP)

    这题确实很棒..又是无想法..其实是AC自动机+DP的感觉,但是只有一个串,用kmp就行了. dp[i][j][k],k代表前缀为virus[k]的状态,len表示其他所有状态串,处理出Ac[len] ...

  7. CF 55D. Beautiful numbers(数位DP)

    题目链接 这题,没想出来,根本没想到用最小公倍数来更新,一直想状态压缩,不过余数什么的根本存不下,看的von学长的blog,比着写了写,就是模版改改,不过状态转移构造不出,怎么着,都做不出来. #in ...

  8. CF 149D Coloring Brackets 区间dp ****

    给一个给定括号序列,给该括号上色,上色有三个要求 1.只有三种上色方案,不上色,上红色,上蓝色 2.每对括号必须只能给其中的一个上色 3.相邻的两个不能上同色,可以都不上色 求0-len-1这一区间内 ...

  9. cf 547B. Mike and Feet dp

    题意: n个矩阵排成一排,n<=2e5,高度分别为hei[i],宽度为1 对于一些连续的矩阵,矩阵的size为矩阵的个数,矩阵的strength为这些矩阵中高度最低的那一个高度 求:for ea ...

随机推荐

  1. Python基础总结之第十一天开始【再深入一下函数,重新认识一下】(新手可相互督促)

    感谢最近大家的关注,希望我的学习笔记对大家有帮助!也感谢各位的评论和推荐,请多多指教. 在重新认识函数之前,我们先看两个函数.一个是我们在前面笔记经常用到的print()  :另一个是input() ...

  2. python 的几种数据类型

    列表  列表是 Python  的主力数据类型.当提到 " 列表 " 时,您脑海中可 能会闪现" 必须进一步声明大小的数组,只能包含同一类对象 "  等想法.千 ...

  3. 基于SpringBoot从零构建博客网站 - 集成editor.md开发发布文章功能

    发布文章功能里面最重要的就是需要集成富文本编辑器,目前富文本编辑器有很多,例如ueditor,CKEditor.editor.md等.这里守望博客里面是集成的editor.md,因为editor.md ...

  4. S2:.net

    1.net框架结构 主要包含公共语言运行时(CLR)和框架类库(.NET Framework 类库 ,FCL) 2.CLR 1.对于一个将要面向.NET平台进行开发的人来说,了解一下.NET平台的整 ...

  5. python_0基础学习_day02

    第二节 一,while while也称为无限循环.死循环 while 条件: 缩进 循环体 应用领域:音乐播放:单曲循环,列表循环,随机播放(也是有规律的) 登陆界面:…… 数学计算:1~100的和, ...

  6. GStreamer流媒体知识介绍

    GStreamer框架 1.GStreamer是什么? 众所周知,Microsoft's Windows和Apple's MacOS对多媒体设备.多媒体创作.播放和实时处理等方面都有很好的支持,而Li ...

  7. ImageView 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  8. 学好C/C++编程,走遍天下都不怕

    C++这门语言从诞生到今天已经经历了将近30个年头.不可否认,它的学习难度都比其它语言较高.而它的学习难度,主要来自于它的复杂性.现在C++的使用范围比以前已经少了很多,java.C#.python等 ...

  9. 学习TensorFlow的第一天

    https://www.cnblogs.com/wangxiaocvpr/p/5902086.html

  10. 《SpringCloud docker》读书笔记

    yml配置意义 当Ribbon和Eureka配合使用时,会自动将虚拟主机名映射成微服务的网络地址. yml中info可以展示一些信息 server: port: 8000 # 指定端口 spring: ...