BZOJ3434 [Wc2014]时空穿梭

摔电脑摔电脑!JZP业界毒瘤!

400题纪念~哇终于上400了的说!!!好不容易欸!

题解什么的还是Orz iwtwiioi

我求组合数的方法明明是O(n)的,为什么这么慢!!!令人报警!

喂,话说这题的重点不在求组合数上面吧。。。

  1 /**************************************************************
  2     Problem: 3434
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:6888 ms
  7     Memory:140824 kb
  8 ****************************************************************/
  9
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13
 14 using namespace std;
 15 const int N = 100005;
 16 const int mod = 10007;
 17 const int Tt = 1005;
 18
 19 int g[21][N], f[21][15][N];
 20 int a[15], p[N], cnt, u[N], mx, mn;
 21 int n[Tt], c[Tt], m[Tt][15];
 22 int C[N][20];
 23 int ans;
 24 bool vis[N];
 25
 26 inline int read() {
 27   int x = 0, sgn = 1;
 28   char ch = getchar();
 29   while (ch < ‘0‘ || ‘9‘ < ch) {
 30     if (ch == ‘-‘) sgn = -1;
 31     ch = getchar();
 32   }
 33   while (‘0‘ <= ch && ch <= ‘9‘) {
 34     x = x * 10 + ch - ‘0‘;
 35     ch = getchar();
 36   }
 37   return sgn * x;
 38 }
 39
 40 int pow(int x, int y) {
 41   int res = 1;
 42   while (y) {
 43     if (y & 1) (res *= x) %= mod;
 44     (x *= x) %= mod;
 45     y >>= 1;
 46   }
 47   return res;
 48 }
 49
 50 void get_f(int N) {
 51   int i, j, k, l;
 52   for (u[1] = 1, i = 2; i <= N; ++i) {
 53     if (!vis[i])
 54       p[++cnt] = i, u[i] = -1;
 55     for (j = 1; j <= cnt; ++j) {
 56       if ((k = i * p[j]) > N) break;
 57       vis[k] = 1;
 58       if (i % p[j] == 0) {
 59     u[k] = 0;
 60     break;
 61       }
 62       u[k] = -u[i];
 63     }
 64   }
 65   for (C[0][0] = i = 1; i <= N; ++i)
 66     for (C[i][0] = j = 1; j < 19; ++j)
 67       C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
 68
 69   for (l = 2; l <= 20; ++l)
 70     for (i = 1; i <= N; ++i)
 71       for (j = i, k = 1; j <= N; j += i, ++k)
 72     (g[l][j] += C[i - 1][l - 2] * u[k]) %= mod;
 73   for (i = 1; i <= N; ++i)
 74     for (l = 2; l <= 20; ++l) {
 75       k = 1;
 76       for (j = 1; j <= 12; ++j) {
 77     f[l][j][i] = (f[l][j][i - 1] + k * g[l][i]) % mod;
 78     (k *= i) %= mod;
 79       }
 80     }
 81 }
 82
 83 void calc(int i, int x) {
 84   memset(a, 0, sizeof(a));
 85   a[1] = 1;
 86   int d1, d2, t, j, k;
 87   for (k = 1; k <= n[i]; ++k) {
 88     t = m[i][k] / x;
 89     d1 = (1ll * t * m[i][k]) % mod;
 90     d2 = (1ll * t * (t + 1) >> 1) % mod;
 91     for (j = n[i] + 1; j > 1; --j)
 92       a[j] =(a[j] * d1 - a[j - 1] * d2) % mod;
 93     (a[1] *= d1) %= mod;
 94   }
 95 }
 96
 97 int main() {
 98   int i, j, k, l, T;
 99   T = read();
100   for (i = 1; i <= T; ++i) {
101     n[i] = read(), c[i] = read();
102     for (j = 1; j <= n[i]; ++j)
103       m[i][j] = read(), mx = max(mx, m[i][j]);
104   }
105   get_f(mx);
106
107   for (i = 1; i <= T; ++i) {
108     ans = 0;
109     for (mn = m[i][1], j = 2; j <= n[i]; ++j)
110       mn = min(mn, m[i][j]);
111     for (j = 1; j <= mn; j = k + 1) {
112       k = mn + 1;
113       for (l = 1; l <= n[i]; ++l)
114     k = min(k, m[i][l] / (m[i][l] / j));
115       calc(i, j);
116       for (l = 1; l <= n[i] + 1; ++l)
117     (ans += a[l] * (f[c[i]][l][k] - f[c[i]][l][j - 1])) %= mod;
118     }
119     ans %= mod;
120     printf("%d\n", (ans += mod) %= mod);
121   }
122   return 0;
123 }

(递推求组合数)

  1 /**************************************************************
  2     Problem: 3434
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:9596 ms
  7     Memory:134184 kb
  8 ****************************************************************/
  9
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13
 14 using namespace std;
 15 const int N = 100005;
 16 const int mod = 10007;
 17 const int Tt = 1005;
 18
 19 int g[21][N], f[21][15][N];
 20 int a[15], p[N], cnt, u[N], mx, mn;
 21 int n[Tt], c[Tt], m[Tt][15];
 22 int fac[N], faci[N], sum[N];
 23 int ans;
 24 bool vis[N];
 25
 26 inline int read() {
 27   int x = 0, sgn = 1;
 28   char ch = getchar();
 29   while (ch < ‘0‘ || ‘9‘ < ch) {
 30     if (ch == ‘-‘) sgn = -1;
 31     ch = getchar();
 32   }
 33   while (‘0‘ <= ch && ch <= ‘9‘) {
 34     x = x * 10 + ch - ‘0‘;
 35     ch = getchar();
 36   }
 37   return sgn * x;
 38 }
 39
 40 int pow(int x, int y) {
 41   int res = 1;
 42   while (y) {
 43     if (y & 1) (res *= x) %= mod;
 44     (x *= x) %= mod;
 45     y >>= 1;
 46   }
 47   return res;
 48 }
 49
 50 inline int C(int x, int y) {
 51   if (y == 0) return 1;
 52   if (x < y) return 0;
 53   if (sum[x] != sum[y] + sum[x - y]) return 0;
 54   return fac[x] * faci[y] % mod * faci[x - y] % mod;
 55 }
 56
 57 void get_f(int N) {
 58   int i, j, k, l;
 59   for (u[1] = 1, i = 2; i <= N; ++i) {
 60     if (!vis[i])
 61       p[++cnt] = i, u[i] = -1;
 62     for (j = 1; j <= cnt; ++j) {
 63       if ((k = i * p[j]) > N) break;
 64       vis[k] = 1;
 65       if (i % p[j] == 0) {
 66     u[k] = 0;
 67     break;
 68       }
 69       u[k] = -u[i];
 70     }
 71   }
 72   fac[0] = faci[0] = 1;
 73   for (fac[1] = 1, i = 2; i <= N; ++i)
 74     if (i % mod == 0) {
 75       sum[i] = sum[i - 1] + 1;
 76       fac[i] = fac[i - 1] * (i / mod) % mod;
 77     } else {
 78       sum[i] = sum[i - 1];
 79       fac[i] = fac[i - 1] * i % mod;
 80     }
 81   for (faci[N] = pow(fac[N], mod - 2),i = N - 1; i; --i)
 82     if ((i + 1) % mod == 0)
 83       faci[i] = faci[i + 1] * ((i + 1) / mod) % mod;
 84     else faci[i] = faci[i + 1] * (i + 1) % mod;
 85
 86   for (l = 2; l <= 20; ++l)
 87     for (i = 1; i <= N; ++i)
 88       for (j = i, k = 1; j <= N; j += i, ++k)
 89     (g[l][j] += C(i - 1, l - 2) * u[k]) %= mod;
 90   for (i = 1; i <= N; ++i)
 91     for (l = 2; l <= 20; ++l) {
 92       k = 1;
 93       for (j = 1; j <= 12; ++j) {
 94     f[l][j][i] = (f[l][j][i - 1] + k * g[l][i]) % mod;
 95     (k *= i) %= mod;
 96       }
 97     }
 98 }
 99
100 void calc(int i, int x) {
101   memset(a, 0, sizeof(a));
102   a[1] = 1;
103   int d1, d2, t, j, k;
104   for (k = 1; k <= n[i]; ++k) {
105     t = m[i][k] / x;
106     d1 = (1ll * t * m[i][k]) % mod;
107     d2 = (1ll * t * (t + 1) >> 1) % mod;
108     for (j = n[i] + 1; j > 1; --j)
109       a[j] =(a[j] * d1 - a[j - 1] * d2) % mod;
110     (a[1] *= d1) %= mod;
111   }
112 }
113
114 int main() {
115   int i, j, k, l, T;
116   T = read();
117   for (i = 1; i <= T; ++i) {
118     n[i] = read(), c[i] = read();
119     for (j = 1; j <= n[i]; ++j)
120       m[i][j] = read(), mx = max(mx, m[i][j]);
121   }
122   get_f(mx);
123
124   for (i = 1; i <= T; ++i) {
125     ans = 0;
126     for (mn = m[i][1], j = 2; j <= n[i]; ++j)
127       mn = min(mn, m[i][j]);
128     for (j = 1; j <= mn; j = k + 1) {
129       k = mn + 1;
130       for (l = 1; l <= n[i]; ++l)
131     k = min(k, m[i][l] / (m[i][l] / j));
132       calc(i, j);
133       for (l = 1; l <= n[i] + 1; ++l)
134     (ans += a[l] * (f[c[i]][l][k] - f[c[i]][l][j - 1])) %= mod;
135     }
136     ans %= mod;
137     printf("%d\n", (ans += mod) %= mod);
138   }
139   return 0;
140 }

(奇怪的组合数求法)

(p.s. 关于那种空间较小的求组合数的方法为什么慢了3秒我也是无言以对。。。)

时间: 2024-10-24 14:58:04

BZOJ3434 [Wc2014]时空穿梭的相关文章

【BZOJ】3434: [Wc2014]时空穿梭

http://www.lydsy.com/JudgeOnline/problem.php?id=3434 题意:n维坐标中要找c个点使得c个点在一条线上且每一维的坐标单调递增且不能超过每一维限定的值m[i](n<=11, 2<=c<=20, m[i]<=100000) #include <bits/stdc++.h> using namespace std; const int N=100005, MD=10007; int C[N][19], g[21][N], f[

BZOJ 3434 Wc2014 时空穿梭 莫比乌斯反演

题目大意:给定一个n维空间,需要在这n维空间内选取c个共线的点,要求这c个点每维坐标均单调递增,第i维坐标是整数且在[1,mi] 为了表述方便令||代表中间东西的方案数 顺便设第i维坐标为ai 但是这样不简洁因此用x表示第1维坐标,y表示第二维坐标,θ表示第n维坐标 貌似我的方法SB了?不管了总之自己能推出来真是太好了- - 尼玛BZOJ渣评测机卡常数- - 明明UOJ5s就全过了的说- - #include <cstdio> #include <cstring> #include

东北育才10天大总结

老师们 Scanf的嗓门照例是最大的.恩. “我是山里的孩子……小的时候背书,整个山头都听得见……” 有一个哈师大附中的竞赛教练很……怎么说呢?接地气好了. Scanf说东北人很耿直,似乎确实是这样的.衡水的教练早就被遣返了…… “他啊,监考去了!” 虽然他不在,但还是不还手机.让衡水的人天天在电脑上颓废…… Scanf不在,你看我们就很老实.他到处“乱”玩,甚至跑到了国境线边,连火车票都忘了买,坐高铁去,乘绿皮火车回,路过长白山就去玩了一趟,结果暴风雪逼得他去吃“暴辣”的烤鱿鱼. “我看<三八

To Do List

妈呀...发现不发博文公布自己要学的东西压力少太多了.......... 然后就会变得颓废..................... 求大家监督QAQ....To Do List是近3天左右目标,3天一更............. (而不是一大版一大版的............. =====================14.02.01-14.02.03:都快要WC了都...再不学点新东西就要滚粗了 可持久化trie:bzoj 2741 莫比乌斯反演(话说我原来写的都是点什么鬼....完全没用

Oracle闪回技术详解

概述: 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复(多数闪回功能都能在数据库联机状态下完成).需要注意的是,闪回技术旨在快速恢复逻辑错误,对于物理损坏或是介质丢失的错误,闪回技术就回天乏术了,还是得借助于Oracle一些高级的备份恢复工具如RAMN去完成(这才是Oracle强大备份恢复机制的精髓所在啊)  撤销段(UNDO SEGMENT) 在讲闪回技术前,需要先了解Oracle中一个逻辑结构--撤销段.因为大部分闪回技术

【codevs 1911 孤岛营救问题】

·为了分析方便,可以先做一个题目简化.去掉"钥匙"这个条件,那么就是一个BFS或者SPFA--现在加上该条件.如本题只给出最多两种钥匙,当然你可以继续坚持BFS等方式,时间不会太差.但是一旦钥匙种类上升至15的时候,就有太多情况需要处理(光说你写BFS的if就是很长的过程,但个人认为时间复杂度依旧能过这道题). ·如图是简化版本的决策方式(为与后文呼应,用SPFA): 大方块是整个地图.小方块是一个房间.那么你可以在向四个方向走,前提是有路可走(没有墙).你本可以轻松拯救大兵瑞恩,然后

男生如何对女朋友好

交友法则,如何对女友好 NO.1 如果你的伴侣要出差一段时间,告诉她你很担心她.你说,你会派出一个保镖来保护她,然后给她一个玩具熊. NO.2 买一袋夜里会发光的星星,粘在你床上正上方的天花板上,拼出“I ? U”的形状.当夜间关掉灯光,你的表白就会显现. NO.3 在某个特定的时刻,送她11枝红玫瑰加一枝塑料红玫瑰.将这枝塑料红玫瑰放在花束的中间,附上一张卡片:我会爱你直到最后一枝玫瑰褪色. NO.4 买下你女友名字的网络域名.创建一个浪漫的页面,让她在上网时不经意间发现这个页面. NO.5

一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁

前续 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(一)——地:起因 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁 平行时空 在复制好上面那一行我就先停下来了,算是先占了个位置,虽然我知道大概要怎么写,不过感觉还是很乱. 我突然想到,既然那么纠结,那么混乱,那么不知所措,我们不如换个视角.记得高中时看过的为数不多的长篇小说<穆斯林的葬礼>,作者是:霍达(女),故事描写了两个发生在不同时代.有着不同的内容却又交错扭结的爱情悲剧,一个是“玉”的故事,一个是“月”

10686 DeathGod不知道的事情

Description 蚂蚁是很强大的动物,除了DeathGod知道的事情外还有很多不知道的!例如… 根据某种理论,时间方向上有无数个平行世界,有的世界蚂蚁很多,有的世界蚂蚁很少,有的世界蚂蚁会繁殖,有的世界蚂蚁不会繁殖. DeathGod没有时空穿梭的能力,因此他无法知道所有的蚂蚁加起来到底有多少.但他知道未来的ACMer非常厉害,可以暂时抛弃肉体,以思维进行时空旅行. 因此他留下一段话给未来的ACMer,让他们帮他数一数,所有的平行世界总共有几只蚂蚁. 由于时间旅行是不可逆的,因此Death