slove  3/12

rank  224

补题   6/12

---------------------------------------------------

hdu 6595

http://acm.hdu.edu.cn/showproblem.php?pid=6595

题意:给一个N,随机一个随机数 n 在[1,N]中,产生长度是[1,n]的全排列,然后输出题目给的函数的期望。

------------------------------------------------

1、题目给的函数一个是求他的子序列的,一个是计算这个序列的逆序数的

2、假设确定n,然后枚举每一种状态,然后会发现规律,对于每一个确定的n,他的期望等于   每个排列的期望逆序数

3、也就等于,这里的sum就是 n 的全排列的逆序对对数总和。

4、打表发现 sum 是由规律的,

5、所以如果确定 n 的值的话,他的期望答案就是 

6、题目要求的是先选 n ,所以答案就是,前 n 项求和后答案是

Code :

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 998244353;
ll power(ll a, ll b)
{ll res = 1;while (b){if (b & 1)res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}
ll a[3005];
int main()
{ll n;ll inv3 = power(3, mod - 2);a[0] = 0;for (ll i = 1; i < 3005; i++){a[i] = i * (i - 1) % mod * inv3 % mod;a[i] = (a[i] + a[i - 1]) % mod;}while (scanf("%lld", &n) > 0){printf("%lld\n", a[n] * power(n, mod - 2) % mod);}
}

hdu 6598

http://acm.hdu.edu.cn/showproblem.php?pid=6598
题意: 
有n个士兵,他们之间有m种联系 
以下m行输入五个数,u,v,A,B,C.
u,v表示两个有联系的士兵,A表示两个士兵都是法师的战斗力,
B表示两个士兵一个是法师一个是战士的战斗力 
C表示两个士兵都是战士的战斗力
现让你分配所有士兵的职业以达到最大战力

---------------------------------------------------------------------
题解:
首先我们考虑一条联系,可以得到一个最小割模型,建一个超级源点和汇点,然后u,v各建一个顶点.
源点,汇点和节点之间连有边,u,v节点之间有一条双向边.
源点与节点之间的边为a,b,汇点与节点之间的边为c,d,节点之间的边为e 
由最小割的定义:求最小代价让源点汇点不连通,然后u,v的阵营也分出来了,要不在源点这边,
要不在汇点这边,假设说在源点这边的为士兵,汇点那边的为法师.
容易得到一个方程组
a+b=A,c+d=C,a+d+e=B,b+c+e=B
五个未知数,四个方程,求不出具体值,但是只要代一组解进去建图就OK了
然后考虑题目要求的是最大代价,有总贡献D=A+B+C 
方程组变为 
a+b=D-A,c+d=D-C,a+d+e=D-B,b+c+e=D-B.
化简得到
a+b=B+C,c+d=A+B,a+d+e=A+C,b+c+e=A+C.
求得的a,b,c,d,e答案就不写了,合法就行 
这样求出来的最小割,再用总贡献-当前求出的最小割即为最大代价了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 1e6+5;
const ll INF = 0x3f3f3f3f;
int n,m,s,t,u[MAX],v[MAX],first[MAX],nextt[MAX],cur[MAX],cnt=0,deep[MAX];
ll w1[MAX],w2[MAX],ans=0,wa[MAX],wb[MAX],wc[MAX],w[MAX];
bool vis[MAX];
void add(int a,int b,int c){u[cnt]=a,v[cnt]=b,w[cnt]=c;nextt[cnt]=first[u[cnt]];first[u[cnt]]=cnt;++cnt;
}
bool bfs(){deque<int>list1;list1.push_back(s);memset(deep,0x3f,sizeof(deep));deep[s]=0;memset(vis,false,sizeof(vis));for(int i=1;i<=n;++i) cur[i]=first[i];vis[s]=true;while(!list1.empty()){int now = list1.front();list1.pop_front();for(int num = first[now];num!=-1;num=nextt[num]){if(!vis[v[num]]&&w[num]>0){vis[v[num]]=true;deep[v[num]]=deep[now]+1; list1.push_back(v[num]);}}}return deep[t]!=INF;
}
int dfs(int now,ll limit){if(!limit||now==t) return limit;int flow=0,length=0;for(int num = first[now];num!=-1;num=nextt[num]){cur[now] = num;if(deep[v[num]]==deep[now]+1 && (length = dfs(v[num],min(limit,w[num])))){flow+=length;w[num]-=length;w[num^1]+=length;limit-=length;if(!limit) break;}}return flow;
}
ll dinic(){ll now=0;while(bfs()) now+=dfs(s,INF);return now;
}
void solve(){while(~scanf("%d%d",&n,&m)){s=n+1,t=n+2,ans=0;memset(first,-1,sizeof(first));memset(w1,0,sizeof(w1));memset(w2,0,sizeof(w2));for(int i=0;i!=m;++i){int a,b;ll c,d,e;scanf("%d%d%lld%lld%lld",&a,&b,&c,&d,&e);w1[a]+=d+e,w1[b]+=d+e,w2[a]+=c+d,w2[b]+=c+d;add(a,b,c+e-2*d),add(b,a,0),add(b,a,c+e-2*d),add(a,b,0);ans+=c+d+e;}for(int i=1;i<=n;++i) add(s,i,w1[i]),add(i,s,0),add(i,t,w2[i]),add(t,i,0);printf("%lld\n",ans-dinic()/2);}
}
int main(void)
{solve();return 0;
}

hdu 6599

http://acm.hdu.edu.cn/showproblem.php?pid=6599

题意:给出一个字符串,求长度为1-n的合法的回文串的个数,合法的意思是当 是回文串并且也是回文串

----------------------------------------------

做法:用回文树求出本质相同的字符串是否合法如果合法就就直接加入,不合法就跳过,这里判断是否合法我用的是马拉车,然后分成判断的区间是奇数还是偶数

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 3e5 + 10;
const int MAXN = 26;
int nex[N][MAXN], fail[N];
ll cnt[N];
int num[N], len[N], s[N], q[N << 1]; /*s用来存放已经插入的字符*/
char str[N]; /*cnt 以i结尾的回文串出现次数 num 以i结尾的回文串种类*/
int last, idx, length;
ll ans[N];
int id[N], r[N<<1];
void newnode(int l)
{len[idx] = l;memset(nex[idx], 0, sizeof(nex[idx]));
}
void init()
{idx = 1, last = 0;len[0] = 0, len[1] = -1;cnt[1] = cnt[0] = 0;num[0] = num[1] = 0;memset(nex[0], 0, sizeof(nex[0]));memset(nex[1], 0, sizeof(nex[1]));length = 0;s[length] = -1;fail[0] = 1;
}
int get_fail(int x)
{while (s[length - len[x] - 1] != s[length])x = fail[x];return x;
}
void insert_pam(int c)
{s[++length] = c;int p = get_fail(last);if (!nex[p][c]){++idx;id[idx] = length;newnode(len[p] + 2);fail[idx] = nex[get_fail(fail[p])][c];nex[p][c] = idx;num[idx] = num[fail[idx]] + 1;}last = nex[p][c];cnt[last]++;
}
void count()
{for (int i = idx; i >= 2; i--)cnt[fail[i]] += cnt[i];
}
void Manacher() {q[0] = '$'; //len字符串原本长度int n = strlen(str + 1);for (int i = 1; i <= n; i++){q[2 * i - 1] = '#';q[2 * i] = str[i];r[2 * i - 1] = r[2 * i] = 0;}n = n * 2;int mxr = 0, mid = 0;//mxr为目前最长回文子串的右端点 mid为mxr对应回文子串的中点 for (int i = 1; i <= n; i++){if (i < mxr)//该点被回文子串包含r[i] = min(mxr - i, r[2 * mid - i]);elser[i] = 1;while (q[i - r[i]] == q[i + r[i]])//扩展 {r[i]++;if (r[i] + i > mxr){mxr = r[i] + i;mid = i;}}}
}
bool check(int x)
{int l = id[x] * 2;int k = (len[x] + 1) / 2;l = l - (k - 1);if (r[l] >= k)return true;return false;
}
int main()
{while (~scanf("%s", str + 1)){init();memset(cnt, 0, sizeof(cnt));int n = strlen(str + 1);memset(ans, 0, sizeof(ans));for (int i = 1; i <= n; i++)insert_pam(str[i] - 'a');count();Manacher();for (int i = 2; i <= idx; i++){if (check(i))ans[len[i]] += cnt[i];}for (int i = 1; i <= n; i++){printf(i == n ? "%lld\n" : "%lld ", ans[i]);}}
}

hdu 6600

http://acm.hdu.edu.cn/showproblem.php?pid=6600

题意:有一个 n 位数 x ,让你给一个数字询问,问最少问多少次能知道 x 的具体的值。输出最少次数的方案数

-----------------------------------------------

枚举每一位,所以查询的次数是 ,注意这里要模1e6+3,所以所有大于等于1e6+3的阶乘都是0。

slove by all

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAX = 1e6 + 3;
const ll mod = 1e6 + 3;
ll ans[MAX];
void init() {ll sum = 1;for (ll i = 1; i < MAX; ++i) {sum *= i;sum %= mod;ans[i] = sum;}
}
void solve() {ll n;init();while (~scanf("%lld", &n)) {if (n >= MAX) printf("0\n");else printf("%lld\n", ans[n]);}
}
int main(void)
{solve();return 0;
}

hdu 6601

http://acm.hdu.edu.cn/showproblem.php?pid=6601

题意:给一个长度为 n 的序列,q 次询问,每次询问区间中能构成的最大三角形。

-------------------------------------------

1、每次查询最多查询45次,就能找到合法答案

2、理由是假设区间中所有数字都是斐波那契数列,第45项大于1e9,所以在这45个数字中,一定有可以构成三角形的三条边

3、主席树找区间第 k 大,然后暴力更新答案,复杂度 

Code :

int main()
{while (scanf("%d%d", &n, &m) > 0){for (int i = 1; i <= n; i++){scanf("%d", &a[i]);t[i - 1] = a[i];}sort(t, t + n);cnt = unique(t, t + n) - t;for (int i = 1; i <= n; i++){int tt = lower_bound(t, t + cnt, a[i]) - t + 1;fp[tt] = a[i];a[i] = tt;}init();for (int i = 1; i <= n; i++){root[i] = root[i - 1];build(a[i], root[i], 1, n);}int ql, qr, k;while (m--){maxn1 = 0;  maxn2 = 0;scanf("%d%d", &ql, &qr);int len = qr - ql + 1;if (len <= 2){printf("-1\n");continue;}maxn1 = query(root[qr], root[ql - 1], len, 1, n);maxn2 = query(root[qr], root[ql - 1], len - 1, 1, n);for (int k = len - 2; k >= 1; k--){int ans = query(root[qr], root[ql - 1], k, 1, n);if (fp[maxn1] < fp[maxn2] + fp[ans]){printf("%lld\n", fp[maxn1] + fp[maxn2] + fp[ans]);goto qwe;}else{maxn1 = maxn2;maxn2 = ans;}}printf("-1\n");qwe:;}}
}

hdu 6602

http://acm.hdu.edu.cn/showproblem.php?pid=6602

题意:n个数字,所有数字的大小在1-C之间,定义好的区间为要么某个数字在区间中出现的次数大于等于k,要么没有出现,求好的区间的最大长度。

1、我们定义一个数字对于一个区间合法为这个数字在这个区间出现次数大于等于k,或者等于0。

2、考虑线段树,维护以当前遍历到的点为右端点,其他点为左端点的这些区间对于多少个数字合法。

3、所以题目就变成了求最左端的值为C的下标。

4、每次更新右端点时

a、以当前这个点为左端点的区间,对于除当前数字外其他所有数字合法,所以这段区间是C-1

b、当前这个点和上一次出现这个点的值之间的所有值,在没有遍历到当前的这个点时,对于当前的数字,都是计算过贡献的,但现在右端点取了这个数字,所以这个数字不一定再对于以中间的这些点为左端点的区间成立,所以中间这一段需要减一。

c、如果当前数字的出现次数大于k,那么说明之前有一段区间对于当前数字又合法了,所以前面的那段区间加一。

5、线段树修改:最大值和标记同时加上val

6、线段树查询:查询值为C 的最靠左边的下标,没有返回-1。

7、线段树查询不能直接查(也可能是本蒟蒻不会),要先打一个标记,记录当前区间最大值的下标,然后区间合并的时候更新一下下标。

Code:

#include <bits/stdc++.h>
#define lson left,mid,k<<1
#define rson mid+1,right,k<<1|1
#define imid int mid=(left+right)/2;
using namespace std;
const int MAXN = 1e5 + 5;
struct node
{int l;int r;int maxn;int mark;int pos;
}que[MAXN * 4];
int C, n, k, ql, qr, val;
void up(int k)
{que[k].maxn = max(que[k << 1].maxn, que[k << 1 | 1].maxn);que[k].pos = (que[k << 1].maxn >= que[k << 1 | 1].maxn) ? que[k << 1].pos : que[k << 1 | 1].pos;
}
void down(int k)
{if (que[k].mark){que[k << 1].mark += que[k].mark;que[k << 1 | 1].mark += que[k].mark;que[k << 1].maxn += que[k].mark;que[k << 1 | 1].maxn += que[k].mark;que[k].mark = 0;}
}
void build(int left = 1, int right = n, int k = 1)
{que[k].l = left;que[k].r = right;que[k].maxn = 0;que[k].mark = 0;if (left == right){que[k].pos = left;return;}imid;build(lson);build(rson);
}
void update(int left = 1, int right = n, int k = 1)
{if (qr < left || right < ql)return;if (ql <= left && right <= qr){que[k].maxn += val;que[k].mark += val;return;}down(k);imid;update(lson);update(rson);up(k);
}
int query(int left = 1, int right = n, int k = 1)
{if (que[k].maxn != C)return -1;if (ql <= left && right <= qr)return que[k].pos;imid;if (ql <= mid){int t = query(lson);if (t != -1)return t;}if (qr > mid){int t = query(rson);if (t != -1)return t;}//return -1;
}
vector<int>v[100005];
int main()
{while (scanf("%d%d%d", &n, &C, &k) > 0){for (int i = 1; i <= C; i++){v[i].clear();v[i].push_back(0);}build();int ans = 0, t;for (int i = 1; i <= n; i++){scanf("%d", &t);ql = qr = i; val = C - 1;update();if (!v[t].empty()){ql = v[t].back() + 1; qr = i - 1; val = -1;update();}v[t].push_back(i);if (v[t].size() > k){ql = v[t][v[t].size() - k - 1] + 1; qr = v[t][v[t].size() - k]; val = 1;update();}ql = 1, qr = i;t = query();if (t != -1)ans = max(ans, i - t + 1);}printf("%d\n", ans);}
}

hdu 多校赛 第二场相关推荐

  1. Swaps and Inversions hdu多校训练第二场 树状数组求逆序数+离散化

    http://acm.hdu.edu.cn/showproblem.php?pid=6318 交换相邻的元素,有几个逆序对,就交换几次使其变成顺序对 #include<bits/stdc++.h ...

  2. ICPC网络赛第二场G Limit

    ICPC网络赛第二场G Limit 题意: 给你数组a和b,求解: 1≤n≤100000,−100≤ai,bi≤100,0≤t≤5.1≤n≤100000,−100≤a_{i},b_{i}≤100,0≤ ...

  3. icpc网络赛第二场K Meal

    icpc网络赛第二场K Meal 题意: 有n个人,n个菜, 现在n个人轮流吃菜,起初S中有n个菜,第i个人会在还没拿走的菜中随机选一个,拿走第j个菜的概率为ai,j∑k∈Sai,k\frac{a_{ ...

  4. 蓝桥杯模拟赛第二场(web)

    文章目录 蓝桥杯模拟赛第二场(web) 1 卡片化标签页 2 随机数生成器 3 个人博客 4 学生成绩统计 5 水果摆盘 6 给页面化个妆 7 小兔子爬楼梯 8 时间管理大师 9 购物车 10 菜单树 ...

  5. 2018 HDU多校第四场赛后补题

    2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...

  6. 2020第十一届蓝桥杯大赛软件类省赛第二场 Java 大学 B 组

    2020第十一届蓝桥杯大赛软件类省赛第二场 Java 大学 B 组 试题 A: 门牌制作(难度:★) 思路: 代码: 试题 B: 寻找 2020(难度:★★) 思路: 代码: 试题 C: 蛇形填数(难 ...

  7. 集美大学第七届团体程序设计天梯赛第二场排位赛题解

    目录 赛事总结 比赛形式 验题 题型 题目难度 L1 L1 - 1 无职转生之转生成何大佬就要拿到ACMWF----『登峰造极』 题目大意 解题思路 代码 L1 - 2 复读机 思路 代码实现 L1 ...

  8. 第十三届蓝桥杯大赛软件赛省赛第二场(Java 大学A组)

    蓝桥杯 2022年省赛真题 Java 大学A组 第二场 试题 A: 练习 试题 B: 超级质数 试题 C: 考勤刷卡 试题 D: 最大和 试题 E: 染色时间 试题 F: k 倍区间 试题 G: 选素 ...

  9. 第十二届蓝桥杯大赛软件赛省赛第二场题解

    文章目录 A: 求余 [问题描述] ans B: 双阶乘 [问题描述] Code C: 格点 [问题描述] code D: 整数分解 [问题描述] 解题思路 code E: 城邦 [问题描述] 解题思 ...

最新文章

  1. 【数字信号处理】序列傅里叶变换 ( 基本序列的傅里叶变换 | 求 1 的傅里叶变换 )
  2. UVA10305 Ordering Tasks
  3. tp和 vue 管理后台管理系统_vue-antd后台管理系统
  4. 最短路径算法整理(二)
  5. Ehcache BigMemory: 摆脱GC困扰(转)
  6. JVM内存结构|程序计数器
  7. zend studio配置php_PHP-Zend Studio PHP环境的搭建
  8. 2015 多校第三场
  9. Nginx_查看并发连接数
  10. SwipeRefreshLayout + RecyclerView 实现 上拉刷新 和 下拉刷新
  11. 实对称矩阵的特征值求法_正交矩阵学习小结
  12. bootdo增加验证码登陆
  13. Windows 好用的护眼软件
  14. order by、distribute by、sort by、group by、partition by
  15. 《精英日课》第三季_2019年四月新书《九个工作谎言》_1工作是具体的,公司是虚拟的
  16. JAVA广度优先搜索---寻找从A点到B点最短路径
  17. ESP32基础应用之使用两个ESP32通过阿里云物联网平台实现相互通信
  18. SpringBoot Junit单元测试
  19. Kubernetes 健康检查之 Readiness 就绪检查
  20. C1认证学习十二(网络拓扑)

热门文章

  1. 【python】plt.cm.Spectral,颜色分配
  2. 第18章异步编程-bloc-自定义状态管理示例-BlocProvider
  3. Ubuntu 16.04启动时进入welcome to emergency mode!
  4. 20201102 门面设计模式
  5. 基于PHP学生成绩查询系统设计与实现 开题报告
  6. 电子表格转web程序控件SpreadsheetWeb v6.0史上最大版本发布 | 附下载
  7. Nancy启用跨站攻击防护(CSRF)
  8. 李筱懿:视频号如何运营才能出爆款?
  9. 实现一个函数,对给定的正整数N,打印从1到N的全部正整数
  10. 春天的马车曲(横光利一)