【LOJ】#2277. 「HAOI2017」方案数
题解
这个出题人完美诠释了什么叫
用心出题,用脚造数据
算完复杂度怎么也得\(O(o^2 * 200)\)略微跑不满,但是有8个测试点虽然有障碍但是一个障碍都不在路径上,2个测试点只有10来个点在路径上
这么轻松愉快的嘛????
如果没有障碍的话只和\(1\)的数量有关
那么我们设\(dp[i][j][k]\)表示第一维有\(i\)个\(1\)第二维有\(j\)个\(1\)第三维有\(k\)个\(1\)的方案数
转移的时候枚举哪一位增加了多少1
方案数是
\(\binom{i}{h}\cdot dp[i - h][j][k] \rightarrow dp[i][j][k]\)
\(\binom{j}{h}\cdot dp[i][j - h][k] \rightarrow dp[i][j][k]\)
\(\binom{k}{h}\cdot dp[i][j][k - h] \rightarrow dp[i][j][k]\)
然后就成功得到80分做完预处理了
然后我没啥好想法了我觉得就设一个\(f[i][j]\)表示走到第\(i\)个点至少经过\(j\)个点
估算一下第二维最多是60 +60 + 60
然后我按照每个点的第一维排序,第一维相等按第二维,第二维相等按第三维,这就是拓扑序了,就暴力更新一下就好了吧(因为感觉跑满复杂度的点不太好造)
结果这不满的也太厉害了吧= =,实际上o<=20了解一下????
update:翻了stdcall的代码发现根本用不上第二维,因为每次转移的时候多了一个点相当于取反一次,所以就是\(O(o^2)\)的
我好菜啊QAQ
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define MAXN 100005
#define mo 974711
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 998244353;
int64 N,M,R,x[10005],y[10005],z[10005];
int dp[64][64][64],C[64][64],ans;
bool vis[10005];
int f[10005],O,cntx[10005],cnty[10005],cntz[10005],id[10005],idx,cn,cm,cr;
int64 lowbit(int64 x) {return x & (-x);}
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int calc(int64 x) {
int cnt = 0;
while(x) {
++cnt;
x -= lowbit(x);
}
return cnt;
}
bool cmp(int a,int b) {
if(x[a] != x[b]) return x[a] < x[b];
if(y[a] != y[b]) return y[a] < y[b];
return z[a] < z[b];
}
void Solve() {
read(N);read(M);read(R);
C[0][0] = 1;
for(int i = 1 ; i <= 62 ; ++i) {
C[i][0] = 1;
for(int j = 1 ; j <= i ; ++j) {
C[i][j] = inc(C[i - 1][j - 1],C[i - 1][j]);
}
}
dp[0][0][0] = 1;
for(int i = 0 ; i <= 62 ; ++i) {
for(int j = 0 ; j <= 62 ; ++j) {
for(int k = 0 ; k <= 62 ; ++k) {
if(!(i + j + k)) continue;
for(int h = 1 ; h <= i ; ++h) dp[i][j][k] = inc(dp[i][j][k],mul(dp[i - h][j][k],C[i][h]));
for(int h = 1 ; h <= j ; ++h) dp[i][j][k] = inc(dp[i][j][k],mul(dp[i][j - h][k],C[j][h]));
for(int h = 1 ; h <= k ; ++h) dp[i][j][k] = inc(dp[i][j][k],mul(dp[i][j][k - h],C[k][h]));
}
}
}
ans = dp[cn = calc(N)][cm = calc(M)][cr = calc(R)];
read(O);
for(int i = 1 ; i <= O ; ++i) {
read(x[i]);read(y[i]);read(z[i]);
cntx[i] = calc(x[i]);cnty[i] = calc(y[i]);cntz[i] = calc(z[i]);
if((x[i] & N) == x[i] && (y[i] & M) == y[i] && (z[i] & R) == z[i]) id[++idx] = i;
}
sort(id + 1,id + idx + 1,cmp);
for(int i = 1 ; i <= idx ; ++i) {
int u = id[i];
f[u] = inc(f[u],MOD - dp[cntx[u]][cnty[u]][cntz[u]]);
ans = inc(ans,mul(f[u],dp[cn - cntx[u]][cm - cnty[u]][cr - cntz[u]]));
for(int k = i + 1 ; k <= idx ; ++k) {
if((x[u] & x[id[k]]) == x[u] && (y[u] & y[id[k]]) == y[u] && (z[u] & z[id[k]]) == z[u]) {
f[id[k]] = inc(f[id[k]],mul(f[u],MOD - dp[cntx[id[k]] - cntx[u]][cnty[id[k]] - cnty[u]][cntz[id[k]] - cntz[u]]));
}
}
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
【LOJ】#2277. 「HAOI2017」方案数的更多相关文章
- LOJ 3094 「BJOI2019」删数——角标偏移的线段树
题目:https://loj.ac/problem/3094 弱化版是 AGC017C . 用线段树维护那个题里的序列即可. 对应关系大概是: 真实值的范围是 [ 1-m , n+m ] :考虑设偏移 ...
- @loj - 2174@ 「FJOI2016」神秘数
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一个可重复数字集合 S 的神秘数定义为最小的不能被 S 的子集的 ...
- loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)
题意 题目链接 Sol 线性基+线段树分治板子题.. 调起来有点自闭.. #include<bits/stdc++.h> #define fi first #define se secon ...
- 【LOJ】#3094. 「BJOI2019」删数
LOJ#3094. 「BJOI2019」删数 之前做atcoder做到过这个结论结果我忘了... em,就是\([1,n]\)之间每个数\(i\),然后\([i - cnt[i] + 1,i]\)可以 ...
- Loj #3056. 「HNOI2019」多边形
Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...
- Loj 3058. 「HNOI2019」白兔之舞
Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...
- Loj #2554. 「CTSC2018」青蕈领主
Loj #2554. 「CTSC2018」青蕈领主 题目描述 "也许,我的生命也已经如同风中残烛了吧."小绿如是说. 小绿同学因为微积分这门课,对"连续"这一概 ...
- Loj #2719. 「NOI2018」冒泡排序
Loj #2719. 「NOI2018」冒泡排序 题目描述 最近,小 S 对冒泡排序产生了浓厚的兴趣.为了问题简单,小 S 只研究对 *\(1\) 到 \(n\) 的排列*的冒泡排序. 下面是对冒泡排 ...
- Loj #3102. 「JSOI2019」神经网络
Loj #3102. 「JSOI2019」神经网络 题目背景 火星探险队发现,火星人的思维方式与人类非常不同,是因为他们拥有与人类很不一样的神经网络结构.为了更好地理解火星人的行为模式,JYY 对小镇 ...
随机推荐
- sadpairs
#include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using ...
- IIS应用程序池相关问题及连接池已满的解决方法
关于应用程序池 在 IIS 6.0 中,引入了应用程序池,应用程序池是将一个或多个应用程序链接到一个或多个工作进程集合的配置.因为应用程序池中的应用程序与其他应用程序被工作进程边界分隔 ...
- NIO[读]、[写]在同一线程(单线程)中执行,让CPU使用率最大化,提高处理效率
前几天写过一篇文章,讨论重写服务后,用ab进行压力测试,发现使用NIO后没提高什么性能,只是CPU使用率提高了,内存占用降低了. 之前的NIO实现模式,主要参考(基于事件的NIO多线程服务器)http ...
- Eclipse启动项目正常,放到tomcat下单独启动就报错的 一例
一个老的ssh的项目,进行二次开发(增加一些新功能)后, 首先用Eclipse中集成的Tomcat启动没有任何问题,但是把启动后的webapps下得目录放到 windows的普通tomcat下单独启动 ...
- div+css感悟
div+css感觉很简单,可是真正做起来一些小细节把握不好,这个网页的布局也是完成不了的.今天学习了一些技巧方法现在分享下: 即一个原则,网页由一个个的大盒子组成,一个个的大盒子里面装着一个个的小盒子 ...
- IAR ------ 基本使用
1.编译结果: 6 887 bytes of readonly code memory 621 bytes of readonly data memory 331 bytes of readwrite ...
- Pycharm使用详解
Pycharm使用详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 古人云,工欲善其事,必先利其器.想要学好Python且拥有高效的开发效率,这个时候每个程序员都有自己的开发方式 ...
- Spark记录-Scala语句(运算符-if-for-while-try-模式匹配)
Scala条件运算符 Scala条件运算符在下表中列出. 运算符 操作 描述 && 与 运算符左侧和右侧的值为true.仅当左侧为真时,右侧才被计算. || 或 左侧或右侧的至少一个值 ...
- 贪心算法:Codevs 1044 拦截导弹
---恢复内容开始--- #include <iostream> #include <cstdio> #include <cstdlib> #include < ...
- Java Message Service学习(一)
一,背景 近期需要用到ActiveMQ接收Oozie执行作业之后的返回结果.Oozie作为消息的生产者,将消息发送给ActiveMQ,然后Client可以异步去ActiveMQ取消息. ActiveM ...