调查问卷

 Accepts: 505
 Submissions: 2436
 Time Limit: 6500/6000 MS (Java/Others)
 Memory Limit: 262144/262144 K (Java/Others)
Problem Description

度度熊为了完成毕业论文,需要收集一些数据来支撑他的论据,于是设计了一份包含 mm 个问题的调查问卷,每个问题只有 'A' 和 'B' 两种选项。

将问卷散发出去之后,度度熊收到了 nn 份互不相同的问卷,在整理结果的时候,他发现可以只保留其中的一部分问题,使得这 nn 份问卷仍然是互不相同的。这里认为两张问卷是不同的,当且仅当存在至少一个被保留的问题在这两份问卷中的回答不同。

现在度度熊想知道,存在多少个问题集合,使得这 nn 份问卷在只保留这个集合的问题之后至少有 kk 对问卷是不同的。

Input

第一行包含一个整数 TT,表示有 TT 组测试数据。

接下来依次描述 TT 组测试数据。对于每组测试数据:

第一行包含三个整数 nn,mm 和 kk,含义同题目描述。

接下来 nn 行,每行包含一个长度为 mm 的只包含 'A' 和 'B' 的字符串,表示这份问卷对每个问题的回答。

保证 1 \leq T \leq 1001≤T≤100,1 \leq n \leq 10^31≤n≤10​3​​,1 \leq m \leq 101≤m≤10,1 \leq k \leq 10^61≤k≤10​6​​,给定的 nn 份问卷互不相同。

Output

对于每组测试数据,输出一行信息 "Case #x: y"(不含引号),其中 x 表示这是第 xx 组测试数据,y 表示满足条件的问题集合的个数,行末不要有多余空格。

Sample Input
Copy

2
2 2 1
AA
BB
2 2 2
AA
BB
Sample Output
Case #1: 3
Case #2: 0   注意到m很小,可以暴力枚举所有的子集然后判断不同的对数是否大于等于k。注意可能有多个人的问卷是一样的。
 #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
int vis[];
char e[][];
int main(){
int t,n,q,m,i,j,cas=,k;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&k);
for(i=;i<n;++i) scanf("%s",e[i]);
int ans=,all=((<<m)-);
for(int i=;i<=all;++i){
int x=,y=;
memset(vis,,sizeof(vis));
for(int j=;j<n;++j){
x=;
for(int k=;k<m;++k){
if(i&(<<k)){
x<<=;
if(e[j][k]=='B') x|=;
}
}
vis[x]++;
}
LL ss=,tmp=;
for(int j=;ss<n;++j){
if(!vis[j]) continue;
tmp+=1LL*vis[j]*(n-ss-vis[j]);
ss+=vis[j];
}
if(tmp>=k)ans++;
}
printf("Case #%d: %d\n",++cas,ans);
}
return ;
}

子串查询

 Accepts: 1706
 Submissions: 7443
 Time Limit: 3500/3000 MS (Java/Others)
 Memory Limit: 262144/262144 K (Java/Others)

Problem Description

度度熊的字符串课堂开始了!要以像度度熊一样的天才为目标,努力奋斗哦!

为了检验你是否具备不听课的资质,度度熊准备了一个只包含大写英文字母的字符串 A[1,n] = a_1 a_2 \cdots a_nA[1,n]=a​1​​a​2​​⋯a​n​​,接下来他会向你提出 qq 个问题 (l,r)(l,r),你需要回答字符串 A[l,r] = a_l a_{l+1} \cdots a_rA[l,r]=a​l​​a​l+1​​⋯a​r​​ 内有多少个非空子串是 A[l,r]A[l,r] 的所有非空子串中字典序最小的。这里的非空子串是字符串中由至少一个位置连续的字符组成的子序列,两个子串是不同的当且仅当这两个子串内容不完全相同或者出现在不同的位置。

记 |S|∣S∣ 为字符串 SS 的长度,对于两个字符串 SS 和 TT ,定义 SS 的字典序比 TT 小,当且仅当存在非负整数 k(\leq \min(|S|,|T|))k(≤min(∣S∣,∣T∣)) 使得 SS 的前 kk 个字符与 TT 的前 kk 个字符对应相同,并且要么满足 |S| = k∣S∣=k 且 |T| > k∣T∣>k,要么满足 k < \min(|S|,|T|)k<min(∣S∣,∣T∣) 且 SS 的第 k+1k+1 个字符比 TT 的第 k+1k+1 个字符小。例如 "AA" 的字典序比 "AAA" 小,"AB" 的字典序比 "BA" 小。

Input

第一行包含一个整数 TT,表示有 TT 组测试数据。

接下来依次描述 TT 组测试数据。对于每组测试数据:

第一行包含两个整数 nn 和 qq,表示字符串的长度以及询问的次数。

第二行包含一个长为 nn 的只包含大写英文字母的字符串 A[1,n]A[1,n]。

接下来 qq 行,每行包含两个整数 l_i,r_il​i​​,r​i​​,表示第 ii 次询问的参数。

保证 1 \leq T \leq 101≤T≤10,1 \leq n,q \leq 10^51≤n,q≤10​5​​,1 \leq l_i \leq r_i \leq n1≤l​i​​≤r​i​​≤n。

Output

对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 xx 组测试数据,接下来 qq 行,每行包含一个整数,表示字符串 A[l,r]A[l,r] 中字典序最小的子串个数,行末不要有多余空格。

Sample Input
1
2 3
AB
1 1
1 2
2 2
Sample Output
Copy

Case #1:
1
1
1   字典序最小的子串,显然长度是1,做个前缀和统计一下不同字母出现的次数就好了。然后找区间内最小的且出现次数不为零的字母就是答案。
  
 #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
char s[];
LL f[][];
int main(){
int t,n,q,m,i,j,k,cas=,l,r;
scanf("%d",&t);
while(t--){
scanf("%d%d%s",&n,&q,s+);
for(i=;i<=n;++i){
for(j=;j<;++j) f[i][j]=f[i-][j];
f[i][s[i]-'A']++;
}
printf("Case #%d:\n",++cas);
while(q--){
scanf("%d%d",&l,&r);
LL ans=;
for(i=;i<;++i){
if(f[r][i]-f[l-][i]){
ans=f[r][i]-f[l-][i];
break;
}
}
printf("%I64d\n",ans);
}
}
return ;
}


序列计数

 Accepts: 89
 Submissions: 566
 Time Limit: 4500/4000 MS (Java/Others)
 Memory Limit: 262144/262144 K (Java/Others)
Problem Description

度度熊了解到,11,22,…,nn 的排列一共有 n! = n \times (n-1) \times \cdots \times 1n!=n×(n−1)×⋯×1 个。现在度度熊从所有排列中等概率随机选出一个排列 p_1p​1​​,p_2p​2​​,…,p_np​n​​,你需要对 kk=11,22,33,…,nn 分别求出长度为 kk的上升子序列个数,也就是计算满足 1 \leq a_11≤a​1​​ < a_2a​2​​ < … < a_ka​k​​ \leq n≤n 且 p_{a_1}p​a​1​​​​ <p_{a_2}p​a​2​​​​< … < p_{a_k}p​a​k​​​​ 的 kk 元组 (a_1a​1​​,a_2a​2​​,…,a_ka​k​​) 的个数。

由于结果可能很大,同时也是为了 ruin the legend, 你只需要输出结果对 1000000007(=10^9+7)1000000007(=10​9​​+7) 取模后的值。

Input

第一行包含一个整数 TT,表示有 TT 组测试数据。

接下来依次描述 TT 组测试数据。对于每组测试数据:

第一行包含一个整数 nn,表示排列的长度。

第二行包含 nn 个整数 p_1p​1​​,p_2p​2​​, …, p_np​n​​,表示排列的 nn 个数。

保证 1 \leq T \leq 1001≤T≤100,1 \leq n \leq 10^41≤n≤10​4​​,TT 组测试数据的 nn 之和 \leq 10^5≤10​5​​,p_1p​1​​,p_2p​2​​,…,p_np​n​​ 是 11,22,…,nn 的一个排列。

除了样例,你可以认为给定的排列是从所有 11,22,…,nn 的排列中等概率随机选出的。

Output

对于每组测试数据,输出一行信息 "Case #x: c_1c​1​​ c_2c​2​​ ... c_nc​n​​"(不含引号),其中 x 表示这是第 xx 组测试数据,c_ic​i​​ 表示长度为 ii 的上升子序列个数对 1000000007(=10^9+7)1000000007(=10​9​​+7) 取模后的值,相邻的两个数中间用一个空格隔开,行末不要有多余空格。

Sample Input
2
4
1 2 3 4
4
1 3 2 4
 
 
 
 
 
   

    不难想到一个O(N*N*log(N))的做法,但是这个数据一直担心会gg,写了之后也确实T了。后来经过大佬指点发现,由于数据是随机的,所以递推到某一个长度之后可能没有任何一种方案,那他之后更大的长度的方案个数也是0,就可以直接退出循环了。加一句话就过了。 
    f(i,j)表示以第i个数结尾的长度为j的上升序列的方案个数,转移的时候用BIT维护下,要保证当前BIT内的数值都是当前位之前的位置贡献的。



 #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
LL mod=1e9+;
int a[],N,M;
LL C[],ans[],f[][];
inline int lowbit(int x){return x&-x;};
inline void add(int x,LL d){
while(x<=N){
C[x]+=d;
C[x]%=mod;
x+=lowbit(x);
}
}
inline LL sum(int x){
LL r=;
while(x){
r+=C[x];
r%=mod;
x-=lowbit(x);
}
return r;
}
inline void scan_d(int &ret)
{
char c;
ret = ;
while ((c = getchar()) < '' || c > '');
while (c >= '' && c <= '')
{
ret = ret * + (c - ''), c = getchar();
}
}
int main(){
int t,n,m,i,j,k,cas=;
char ch;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
N=n;
for(i=;i<=n;++i) scan_d(a[i])/*scanf("%d",a+i)*/,f[][i]=;
ans[]=n;
int cur=;
for(int len=;len<=n;++len){
ans[len]=;
if(ans[len-]==) continue;
for(i=;i<=n;++i){
LL tmp=sum(a[i]-);
ans[len]+=tmp;
add(a[i],f[cur^][i]);
f[cur][i]=tmp; }
//memset(C,0,sizeof(C));
for(i=;i<=n;++i)C[i]=;
cur^=;
}
printf("Case #%d:",++cas);
for(i=;i<=n;++i) printf(" %I64d",ans[i]%mod);
cout<<endl;
}
return ;
}

三原色图

 Accepts: 210
 Submissions: 865
 Time Limit: 1500/1000 MS (Java/Others)
 Memory Limit: 262144/262144 K (Java/Others)

Problem Description

度度熊有一张 nn 个点 mm 条边的无向图,所有点按照 1,2,\cdots,n1,2,⋯,n 标号,每条边有一个正整数权值以及一种色光三原色红、绿、蓝之一的颜色。

现在度度熊想选出恰好 kk 条边,满足只用这 kk 条边之中的红色边和绿色边就能使 nn 个点之间两两连通,或者只用这 kk 条边之中的蓝色边和绿色边就能使 nn 个点之间两两连通,这里两个点连通是指从一个点出发沿着边可以走到另一个点。

对于每个 k=1,2,\cdots,mk=1,2,⋯,m,你都需要帮度度熊计算选出恰好 kk 条满足条件的边的权值之和的最小值。

Input

第一行包含一个正整数 TT,表示有 TT 组测试数据。

接下来依次描述 TT 组测试数据。对于每组测试数据:

第一行包含两个整数 nn 和 mm,表示图的点数和边数。

接下来 mm 行,每行包含三个整数 a,b,wa,b,w 和一个字符 cc,表示有一条连接点 aa 与点 bb 的权值为 ww、颜色为 cc 的无向边。

保证 1 \leq T \leq 1001≤T≤100,1 \leq n,m \leq 1001≤n,m≤100,1 \leq a,b \leq n1≤a,b≤n,1 \leq w \leq 10001≤w≤1000,c \in {R,G,B}c∈{R,G,B},这里 R,G,BR,G,B 分别表示红色、绿色和蓝色。

Output

对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 xx 组测试数据,接下来 mm 行,每行包含一个整数,第 ii 行的整数表示选出恰好 ii 条满足条件的边的权值之和的最小值,如果不存在合法方案,输出 -1−1,行末不要有多余空格。

Sample Input
1
5 8
1 5 1 R
2 1 2 R
5 4 5 R
4 5 3 G
1 3 3 G
4 3 5 G
5 4 1 B
1 2 2 B
Sample Output
Copy

Case #1:
-1
-1
-1
9
10
12
17
22       跑两次kruscal就好了,一次只用条件一的边,一次用条件二的边。每次跑完之后在依次加入剩下的边更新ans,如果无法联通答案就都是-1了。
 #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
int f[];
int getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
struct Edge{
int u,v,w,col,sel;
bool operator<(const Edge& C)const{
return w<C.w;
}
}e[];
int ans[],N,M;
void mst(int no){
int cnt=,cnw=;
for(int i=;i<=N;++i)f[i]=i;
for(int i=;i<=M;++i)e[i].sel=;
for(int i=;cnt<N-&&i<=M;++i){
if(e[i].col==no) continue;
int fu=getf(e[i].u),fv=getf(e[i].v);
if(fu!=fv){
e[i].sel=;
cnt++;
cnw+=e[i].w;
f[fv]=fu;
}
}
if(cnt!=N-) return;
if(ans[cnt]==-) ans[cnt]=cnw;
else ans[cnt]=min(ans[cnt],cnw);
for(int i=;i<=M;++i){
if(e[i].sel) continue;
cnt++;
cnw+=e[i].w;
if(ans[cnt]==-) ans[cnt]=cnw;
else ans[cnt]=min(ans[cnt],cnw);
}
}
int main(){
int t,n,m,i,j,k,cas=;
char ch;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
N=n,M=m;
for(i=;i<=m;++i){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
//getchar();scanf("%c",&ch);
cin>>ch;
if(ch=='R') e[i].col=;
else if(ch=='G') e[i].col=;
else if(ch=='B') e[i].col=;
}
sort(e+,e++m);
memset(ans,-,sizeof(ans));
mst();
mst(); printf("Case #%d:\n",++cas);
for(i=;i<=m;++i) printf("%d\n",ans[i]);
}
return ;
}


2018"百度之星"程序设计大赛 - 资格赛 A/B/E/F的更多相关文章

  1. 2018"百度之星"程序设计大赛 - 资格赛 - 题集

    1001 $ 1 \leq m \leq 10 $ 像是状压的复杂度. 于是我们(用二进制)枚举留下的问题集合 然后把这个集合和问卷们的答案集合 $ & $ 一下 就可以只留下被选中的问题的答 ...

  2. 2018"百度之星"程序设计大赛 - 资格赛hdu6349三原色(最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6349 题目: 三原色图 Time Limit: 1500/1000 MS (Java/Others)  ...

  3. 2018"百度之星"程序设计大赛 - 资格赛 1002 子串查询

    题面又是万能的毒毒熊... 实在不想写了,就只写了这题 记26个前缀和查询枚举最小值直接算 实在是氵的死 而且我忘记输出Case #%d 想了很久 >_< #include<bits ...

  4. 子串查询(二维前缀数组) 2018"百度之星"程序设计大赛 - 资格赛

    子串查询 Time Limit: 3500/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  5. 2018"百度之星"程序设计大赛 - 资格赛

    调查问卷  Accepts: 1546  Submissions: 6596  Time Limit: 6500/6000 MS (Java/Others)  Memory Limit: 262144 ...

  6. HDU6383 2018 “百度之星”程序设计大赛 - 初赛(B) 1004-p1m2 (二分)

    原题地址 p1m2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  7. HDU6380 2018 “百度之星”程序设计大赛 - 初赛(B) A-degree (无环图=树)

    原题地址 degree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  8. hdu 6082 度度熊与邪恶大魔王(2017"百度之星"程序设计大赛 - 资格赛 )

    度度熊与邪恶大魔王 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. 2014年百度之星程序设计大赛 - 资格赛 第二题 Disk Schedule

    双调欧几里得旅行商问题是一个经典动态规划问题.<算法导论(第二版)>思考题15-1和北京大学OJ2677都出现了这个题目. 旅行商问题描写叙述:平面上n个点,确定一条连接各点的最短闭合旅程 ...

随机推荐

  1. Console的9种用法

    Console的9种用法,1.显示信息的命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html> <html> <he ...

  2. spring注解预览

    从Java5.0开始,Java开始支持注解.Spring做为Java生态中的领军框架,从2.5版本后也开始支持注解.相比起之前使用xml来配置Spring框架,使用注解提供了更多的控制Spring框架 ...

  3. 在Mac OSX下安装Microsoft Calibri字体

    参考: Where can I find default Microsoft fonts Calibri, Cambria? 在Mac OSX下安装Microsoft Calibri字体 1.下载: ...

  4. Java LocalDateTime,DateTimeFomatter----JDK8新时间类的简单使用

    JDK8中增加了一系列时间的类, (据说)是为了干掉过去的Date,Calendar类的, 过去的Date类(据说)有着线程不安全等诸多弊端, 至于我的个人感受就是用起来实在是很麻烦,我一般封装成几个 ...

  5. 【BZOJ】3926: [Zjoi2015]诸神眷顾的幻想乡

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机... 久仰公之大名啊... 太阳花田的结构比较特殊,只与一个空地相邻 ...

  6. php CLI SAPI 内置Web Server

    PHP 5.4.0起, CLI SAPI 提供了一个内置的Web服务器. 这个内置的Web服务器主要用于本地开发使用,不可用于线上产品环境. URI请求会被发送到PHP所在的的工作目录(Working ...

  7. 力扣(LeetCode) 849. 到最近的人的最大距离

    在一排座位( seats)中,1 代表有人坐在座位上,0 代表座位上是空的. 至少有一个空座位,且至少有一人坐在座位上. 亚历克斯希望坐在一个能够使他与离他最近的人之间的距离达到最大化的座位上. 返回 ...

  8. 学习笔记7—python 列表,数组,矩阵两两转换tolist()

    from numpy import *   a1 =[[1,2,3],[4,5,6]] #列表 print('a1 :',a1) #('a1 :', [[1, 2, 3], [4, 5, 6]])   ...

  9. Python Scrapy 爬虫框架实例(一)

    之前有介绍 scrapy 的相关知识,但是没有介绍相关实例,在这里做个小例,供大家参考学习. 注:后续不强调python 版本,默认即为python3.x. 爬取目标 这里简单找一个图片网站,获取图片 ...

  10. Python量化库大全

    https://zhuanlan.zhihu.com/p/26983703?utm_source=wechat_session&utm_medium=social 这个网址上详细介绍了,做量化 ...