调查问卷

 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. Linux安装svn客户端

    Red Hat Linux 1.安装$ yum install subversion 2.常见问题1.执行svn报错:cannot set LC_CTYPE localevi /etc/profile ...

  2. C语言学习之桶排序

    之前的博文写了交换(冒泡)排序.选择排序,本文就写写桶排序.不过我理解的这样不算是真正上的桶排序,我的比较简单而真正的桶排序是比较复杂的,暂且就叫桶排序吧. 桶排序在排序中应该用的不多吧,个人理解的是 ...

  3. centos7 修改密码

    Centos7破解密码的方法   Centos7忘记密码   在工作或者自己练习的时候我们难免会大意忘掉自己的root密码,有些同学忘掉密码竟然第一选择是重装系统,工作中可万万使不得! 本篇博客将讲解 ...

  4. mac删除python

    删除Python框架 sudo rm -rf /Library/Frameworks/Python.framework/Versions/x.x 删除Python本程序 sudo rm -rf &qu ...

  5. Python pycharm 常用快捷键

    快捷键 1.编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性) Ctrl + Alt + Space 快速导入任意类 Ctrl + Shift + Enter 语句完成 ...

  6. JSONObject的parseArray方法作用。

    该方法将字符串数据转换成集合对象. String dep_tree = JedisUtils.getInstance().get(CacheConstant.DEP_TREE, user.getId( ...

  7. python 拷贝文件

    使用绝对目录: import os import shutil shutil.copyfile("/opt/test/update.tar.gz","/opt/updat ...

  8. wxss与rpx

    WXSS(WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式. WXSS 用来决定 WXML 的组件应该怎么显示. 为了适应广大的前端开发者,WXSS 具有 CSS ...

  9. 排序——选择排序(java描述)

    百度百科的描述如下:选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元 ...

  10. display: none; 与 jq show方法之间的联系

    1. 定义四种常用隐藏元素的方式,然后调用  jq 的 show 方法显示,观察各原先隐藏元素的   display   表现,结合 jq 源码,show 方法设置 元素 display  属性值为 ...