Codeforces 1111D Destroy the Colony 退背包 (看题解)
第一次知道这种背包还能退的。。。。
我们用dp[ i ]表示选取若干个物品重量到达 i 的方案数。
如果我们g[ i ]表示不用第 x 个物品的, 然后选若干其他的物品到达 i 的方案数。
if(i < cnt[ x ]) g[ i ] = dp[ i ]
else g[ i ] = dp[ i ] - g[ i - cnt[ x ] ]
这样退一次就能删一个物品, 这个题目退两次就可以了。
一共只有52 × 52 / 2个本质不同的询问, 预处理一下。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 1e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ;
const double eps = 1e-;
const double PI = acos(-); int n, m, q, way, c[];
int dp[N], f[N], g[N], ans[][];
char s[N];
int F[N], Finv[N], inv[N]; int getPos(char x) {
if(islower(x)) return x - 'a';
else return x - 'A' + ;
} void add(int &a, int b) {
a += b; if(a >= mod) a -= mod;
} void init() {
inv[] = F[] = Finv[] = ;
for(int i = ; i < N; i++) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
for(int i = ; i < N; i++) F[i] = 1ll * F[i - ] * i % mod;
for(int i = ; i < N; i++) Finv[i] = 1ll * Finv[i - ] * inv[i] % mod;
} int main() {
init();
scanf("%s", s + );
n = strlen(s + );
for(int i = ; i <= n; i++)
c[getPos(s[i])]++;
m = n / ;
way = 1ll * F[m] * F[m] % mod;
for(int i = ; i < ; i++)
way = 1ll * way * Finv[c[i]] % mod;
dp[] = ;
for(int i = ; i < ; i++) {
if(!c[i]) continue;
for(int j = n - c[i]; j >= ; j--)
add(dp[j + c[i]], dp[j]);
}
for(int u = ; u < ; u++) {
for(int v = u + ; v < ; v++) {
if(!c[u] || !c[v]) continue;
for(int i = ; i <= n; i++) {
if(i < c[u]) f[i] = dp[i];
else {
f[i] = dp[i] - f[i - c[u]];
if(f[i] < ) f[i] += mod;
}
if(i < c[v]) g[i] = f[i];
else {
g[i] = f[i] - g[i - c[v]];
if(g[i] < ) g[i] += mod;
}
}
ans[u][v] = * g[m] % mod;
}
}
scanf("%d", &q);
while(q--) {
int x, y; scanf("%d%d", &x, &y);
x = getPos(s[x]), y =getPos(s[y]);
if(x > y) swap(x, y);
if(x == y) {
printf("%d\n", 1ll * dp[m] * way % mod);
} else {
printf("%d\n", 1ll * ans[x][y] * way % mod);
}
}
return ;
} /*
*/
Codeforces 1111D Destroy the Colony 退背包 (看题解)的更多相关文章
- Codeforces1111D Destroy the Colony 退背包+组合数
Codeforces1111D 退背包+组合数 D. Destroy the Colony Description: There is a colony of villains with severa ...
- CF - 1111D Destroy the Colony DP
题目传送门 题意: 这个题目真的是最近遇到的最难读. 有一个长度n的字符串,每一位字符都代表的是该种种类的敌人. 现在如果一个序列合法的话,就是同一种种类的敌人都在字符串的左半边或者右半边. 现在有q ...
- Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)
Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...
- Codeforces 311D Interval Cubing 数学 + 线段树 (看题解)
Interval Cubing 这种数学题谁顶得住啊. 因为 (3 ^ 48) % (mod - 1)为 1 , 所以48个一个循环节, 用线段树直接维护. #include<bits/stdc ...
- Codeforces 498B Name That Tune 概率dp (看题解)
Name That Tune 刚开始我用前缀积优化dp, 精度炸炸的. 我们可以用f[ i ][ j ] 来推出f[ i ][ j + 1 ], 记得加加减减仔细一些... #include<b ...
- 【Codeforces1111D_CF1111D】Destroy the Colony(退背包_组合数学)
题目: Codeforces1111D 翻译: [已提交至洛谷CF1111D] 有一个恶棍的聚居地由几个排成一排的洞穴组成,每一个洞穴恰好住着一个恶棍. 每种聚居地的分配方案可以记作一个长为偶数的字符 ...
- Codeforces 1111D(退背包、排列组合)
要点 优质题解 因为只有某type坏人全部分布在同一撇时,才能一次消灭.所以题目安排完毕后一定是type(x)和type(y)占一半,其余占另一半. 实际情况只有52*52种,则预处理答案 枚举某两种 ...
- BZOJ.2287.[POJ Challenge]消失之物(退背包)
BZOJ 洛谷 退背包.和原DP的递推一样,再减去一次递推就行了. f[i][j] = f[i-1][j-w[i]] + f[i-1][j] f[i-1][j] = f[i][j] - f[i-1][ ...
- [CF1111D]Destroy the Colony
题目大意:有一个长度为$n(n\leqslant10^5,n=0\pmod2)$的字符串,字符集大小为$52$,有$q(q\leqslant10^5)$次询问,每次询问第$x,y$个字符在这个字符串的 ...
随机推荐
- 【原创】大数据基础之Hive(5)hive on spark
hive 2.3.4 on spark 2.4.0 Hive on Spark provides Hive with the ability to utilize Apache Spark as it ...
- Gradle缓存目录文件命名规则
在打开Android Studio项目的时候,会下载项目对应版本的gradle,该版本是在项目根目录下\gradle\wrapper\gradle-wrapper.properties文件中指定的: ...
- 关于main函数的参数问题
我们经常用的main函数都是不带参数的.因此main 后的括号都是空括号.实际上,main函数可以带参数,这个参数可以认为是 main函数的形式参数.C语言规定main函数的参数只能有两个, 习惯上这 ...
- swift 实践- 03 -- UILabel
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 标签 let ...
- vuejs中使用echarts
<style scoped> .content { /*自行添加样式即可*/ } #main { /*需要制定具体高度,以px为单位*/ height: 400px; } </sty ...
- java多线程快速入门(二十)
1.Java.util的线程安全工具类 Vector(线程安全) ArrayList(线程不安全) HashTable(线程安全) HashMap(线程不安全) 2.将线程不安全集合变为线程安全集合 ...
- IE11总是有缓存的问题
F12,里面选择网络,始终从服务器刷新..
- bzoj3991 lca+dfs序应用+set综合应用
/* 给定一棵树,树上会出现宝物,也会有宝物消失 规定如果要收集树上所有宝物,就要选择一个点开始,到每个宝物点都跑一次,然后再回到那个点 现在给定m次修改,每次修改后树上就有一个宝物消失,或者一个宝物 ...
- git使用diff----git-pull之后如何查看拉下来的文件有那些修改
git pull拉取 git pull对于拉下来的修改文件自动对其进行git add /rm 及git commit 操作.所以拉下来的文件有那些修改,查看的方式可把它们归结于上一次提交的比较. gi ...
- C++ StrCat()
关于StrCat function,参考:https://msdn.microsoft.com/en-us/library/windows/desktop/bb759925(v=vs.85).aspx ...