题目传送门

题意:

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

有一个长度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. 【Spring】org.springframework.web.context.ContextLoaderListen 报错

    详细信息如下: org.apache.catalina.core.StandardContext.listenerStart Error configuring application listene ...

  2. 【iOS】打印方法名

    为了便于追踪程序运行过程,可以在日志打印方法名,示例代码如下: NSLog(@"%@", NSStringFromSelector(_cmd)); 结果如图所示: 此外,在多个中, ...

  3. 洛谷P2763题解

    吐槽一下:蜜汁UKE是什么玩意?! 题目分析: 观察题面,对于给定的组卷要求,计算满足要求的组卷方案,可以发现这是一道明显的有条件的二分图匹配问题,于是考虑建模. 建一个超级源点,一个超级汇点:源点与 ...

  4. C语言tips_1 关于&& || ! 的优先级

    关于&& || ! 三种操作的优先级 测试如下 简要分析 假设&&>|| 则结果为1 假设||>&& 则结果为0 结果为1 得证 & ...

  5. NodeJs小试牛刀--聊天室搭建

    最近研究聊天室功能,准备用nodejs实现.下面是自己的尝试!! nodejs的安装这里就不详细赘述了. 程序创建 引入required模块 var express = require('expres ...

  6. 不相交路径[BZOJ1471] 容斥原理 拓扑排序

    最近学容斥的时候又碰到一道类似的题目,所以想分享一个套路,拿这题来举例 [题目描述] 给出一个\(N(N\leq 150)\)个结点的有向无环简单图.给出4个不同的点\(a,b,c,d\),定义不相交 ...

  7. 对平底锅和垃圾的O奖论文的整理和学习[2](2018-02-08发布于知乎)

    其实这篇论文看了一段时间,愣是没看出来这个模型怎么建立的.虽然看不懂,但是有一些部分还是很喜欢. 首先是摘要: 摘要分为八段 第一段:背景引入,太空垃圾的问题日益严重. 第二段:本文工作,包括基本的i ...

  8. jupyter iPython web sit use 1

    I want Jupyter to print all the interactive output without resorting to print, not only the last res ...

  9. flask入门 七行代码讲解

    # 导包 从flask里面导入Flask这个对象.from flask import Flask # 实例化一个对象,app = Flask(__name__) # 里面的 __name__ 是为了定 ...

  10. 【雕爷学编程】Arduino动手做(16)---数字触摸传感器

    37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...