orz lydrainbowcat

[Problem A]「艦これ市」70万幕后交易事件

排序机器=-=。重要的是相同的处理。

我们可以从小到大添加数字,然后维护一个位置的序列。每一种相等的数字都在一块。如果我们要添加一个新的数字,要把位置>它的数字全部弹出,而且要把小于它的数字(在队头)全部弹出,这样才能保证正确性和最优性。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; #define maxn 1000010 int n, m, ans; int a[maxn]; vector<int> b[maxn]; int q[maxn]; int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
scanf("%d", &a[i]);
b[a[i]].push_back(i);
m = max(m, a[i]);
}
int l = 1, r = 0;
for(int i = 1; i <= m; i ++){
int N = b[i].size();
for(int j = N - 1; j >= 0; j --){
int k = b[i][j];
while(l <= r && q[r] > k){
while(l <= r && a[q[l]] < a[q[r]])
l ++;
r --;
}
ans = max(ans, r - l + 1 + N - j);
}
for(int j = 0; j < b[i].size(); j ++)
q[++ r] = b[i][j];
}
printf("%d\n", n - ans);
return 0;
}

[Problem B]「NOIP市」神秘PY交易事件(前篇)  

题目意思好长。。

而且两个人同能力要相等的工资??

暴力都写炸了。。QAQ。。

bruteforce:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define maxn 100010
using namespace std; struct Edge{
int to, next, dis;
Edge(int v = 0, int nxt = 0, int d = 0){
to = v, next = nxt, dis = d;
}
}edge[maxn << 2]; int h[maxn], cnt, n;
void add(int u, int v, int d){
edge[++ cnt] = Edge(v, h[u], d); h[u] = cnt;
} int dis[maxn];
queue<int>Q;
bool vis[maxn];
void Spfa(){
int ans = 0;
for(int i = 1; i <= n; i ++)
add(0, i, 1);
Q.push(0);
memset(dis, 0x80, sizeof dis);
dis[0] = 0;
while(!Q.empty()){
int u = Q.front(); Q.pop();
for(int i = h[u]; i; i = edge[i].next){
int v = edge[i].to;
if(dis[v] < dis[u] + edge[i].dis){
dis[v] = dis[u] + edge[i].dis;
if(vis[v] == false)
vis[v] = true, Q.push(v);
}
}vis[u] = false;
}
for(int i = 1; i <= n; i ++)
ans += dis[i]; printf("%d\n", ans);
} int c[maxn]; Edge G[maxn << 2];
int H[maxn], CNT;
void Ins(int u, int v){
CNT ++;
G[CNT].to = v;
G[CNT].next = H[u];
H[u] = CNT;
} int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d", &c[i]);
int u, v, m;
scanf("%d", &m);
for(int i = 1; i <= m; i ++){
scanf("%d%d", &u, &v);
Ins(u, v); Ins(v, u);
} for(int i = 1; i <= n; i ++){
for(int j = H[i]; j; j = G[j].next){
int v = G[j].to;
if(c[i] < c[v])
add(i, v, 1);
if(c[i] == c[v])
add(i, v, 0), add(v, i, 0);
for(int k = H[i]; k; k = G[k].next){
int u = G[k].to;
if(c[v] < c[u])
add(v, u, 1);
if(c[v] == c[u])
add(v, u, 0), add(u, v, 0);
}
}
}
Spfa();
return 0;
}

然而正解是这样的。。对于相邻的人,如果能力值相同那么工资一定相同。这样工资相同的人可能会组成一些强连通分量,我们如果把这些scc缩掉就会形成一个DAG。(这个可以用并查集实现)。跑差分约束(最长路)或者拓扑排序都可。然后对于每一个点相邻的sort一遍,由于相邻的人的的能力值都不同,所以可以在相邻点之间连边即可(建边优化)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#define maxn 100010
using namespace std; vector<int> G[maxn]; int c[maxn]; bool cmp(int i, int j){return c[i] < c[j];} struct Edge{
int to, next;
Edge(int v = 0, int nxt = 0){
to = v, next = nxt;
}
}edge[maxn << 4];
int h[maxn], cnt, n, In[maxn];
void add(int u, int v){
edge[++ cnt] = Edge(v, h[u]);
h[u] = cnt; ++ In[v];
} int fa[maxn];
int getfa(int x){return x == fa[x] ? x : fa[x] = getfa(fa[x]);}
inline void Union(int x, int y){
x = getfa(x), y = getfa(y);
fa[x] = y;
} stack<int> S; int ans[maxn], ct[maxn]; int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d", &c[i]), fa[i] = i;
int u, v, m;
scanf("%d", &m);
for(int i = 1; i <= m; i ++){
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
if(c[u] == c[v])
Union(u, v);
} for(int i = 1; i <= n; i ++){
sort(G[i].begin(), G[i].end(), cmp);
for(int j = 1; j < G[i].size(); j ++)
if(c[G[i][j]] == c[G[i][j-1]])
Union(G[i][j], G[i][j-1]);
} for(int i = 1; i <= n; i ++){
for(int j = 0; j < G[i].size(); j ++)
if(c[i] < c[G[i][j]])
add(getfa(i), getfa(G[i][j]));
for(int j = 1; j < G[i].size(); j ++)
if(getfa(G[i][j-1]) != getfa(G[i][j]))
add(getfa(G[i][j-1]), getfa(G[i][j]));
} for(int i = 1; i <= n; i ++)
if(In[i] == 0 && getfa(i) == i)
S.push(i); for(int i = 1; i <= n; i ++)
ct[getfa(i)] ++, ans[i] = 1;
long long ret = 0;
while(!S.empty()){
int u = S.top(); S.pop();
ret += 1ll * ct[u] * ans[u];
for(int i = h[u]; i; i = edge[i].next){
int v = edge[i].to;
In[v] --;
ans[v] = max(ans[v], ans[u] + 1);
if(In[v] == 0) S.push(v);
}
} printf("%lld\n", ret);
return 0;
}

  

Contest Hunter Round #70 - 连续两大交易事件杯省选模拟赛的更多相关文章

  1. 模拟赛小结:2017 China Collegiate Programming Contest Final (CCPC-Final 2017)

    比赛链接:传送门 前期大顺风,2:30金区中游.后期开题乏力,掉到银尾.4:59绝杀I,但罚时太高卡在银首. Problem A - Dogs and Cages 00:09:45 (+) Solve ...

  2. Codeforces Beta Round #70 (Div. 2)

    Codeforces Beta Round #70 (Div. 2) http://codeforces.com/contest/78 A #include<bits/stdc++.h> ...

  3. Gartner 2018 数据库系列报告发布 巨杉数据库连续两年入选

    近期,Gartner陆续发布了2018年的数据库系列报告,包括<数据库魔力象限><数据库核心能力>以及<数据库推荐报告>.其中,SequoiaDB巨杉数据库作为业界 ...

  4. 首先java中集合类主要有两大分支

    本文仅分析部分原理和集合类的特点,不分析源码,旨在对java的集合类有一个整体的认识,理解各个不同类的关联和区别,让大家在不同的环境下学会选择不同的类来处理. Java中的集合类包含的内容很多而且很重 ...

  5. [转帖] 中国SaaS死或生之二: ERP两大邪术,尽出歪门邪路 ---- 挺好玩的

    中国SaaS死或生之二: ERP两大邪术,尽出歪门邪路   http://www.cniteyes.com/archives/33753   文章摘要:在数字化浪潮中,油腻ERP大叔的那些“歪门邪术” ...

  6. BCH硬分叉在即,Bitcoin ABC和NChain两大阵营PK

    混迹币圈,我们都知道,BTC分叉有了BCH,而近期BCH也将面临分叉,这次分叉将是Bitcoin ABC和NChain两大阵营的较量,最后谁能成为主导,我们拭目以待. 比特币现金(BCH)的价格自上周 ...

  7. Contest Hunter 3101

    题目 Contest Hunter 3101 阶乘分解 原题传送门 题目分析 这里介绍一个本蒟蒻自己\(yy\)出来的方法. 我们发现,对于某一个单个的整数\(n\),若\(n\)能被某一个数\(x\ ...

  8. 【题解】Comet OJ Round 70 简要题解

    [题解]Comet OJ Round 70 简要题解 A 将放在地上的书按照从小到大排序后,问题的本质就变成了合并两个序列使得字典序最小.可以直接模拟归并排序.直接用循环和std::merge实现这个 ...

  9. 痞子衡嵌入式:串行NAND Flash的两大特性导致其在i.MXRT FlexSPI下无法XiP

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串行NAND Flash的两大特性导致其在i.MXRT FlexSPI下无法XiP. 在嵌入式世界里,当我们提起XiP设备(支持代码原地 ...

随机推荐

  1. django-cms 代码研究(四)CMS_TEMPLATE标签

    CMS_TEMPLATE 继承这个东东可以在实现很灵活的布局,如下:

  2. django静态文件查找逻辑

    最近被django的静态文件配置整疯了. 决定直捣黄龙,看看底层代码: 首先用manage finstatic xxxx.js 看看处理逻辑,发现主要在:C:\Python27\Lib\site-pa ...

  3. 21.左旋转字符串[LeftRotateString]

    [题目] 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部.如把字符串AB1234 左旋转2位得到字符串1234AB.请实现字符串左旋转的函数.要求时间对长度为n的字符串操作的复杂度 ...

  4. 越狱后天气闪退 iPhone5天气闪退解决方法

    iPhone5天气闪退解决方法: 第一步:前往Cydia卸载AppSync; 第二步:通过iTools删除/var/mobile/Library/Caches/com.apple.mobile.ins ...

  5. ubuntu下常用服务器的构建

    1 ftp 1.1 ftp服务器 1.安装vsftpd服务器 sudo apt-get install vsftpd 2.配置vsftpd.conf文件 sudo vi /etc/vsftpd.con ...

  6. error: insufficient permissions for device: verify udev rules

    error: insufficient permissions for device: verify udev rules.See [http://developer.android.com/tool ...

  7. hdu 1195:Open the Lock(暴力BFS广搜)

    Open the Lock Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  8. linux tricks 之 roundup.

    转载:http://stackoverflow.com/questions/1010922/question-about-round-up-macro 以下内容转载自stackoverflow关于 r ...

  9. vijos 1038 括号+路径 ***

    链接:点我 就是自己写不出来 #include <cstdio> #include <climits> #include <memory.h> using name ...

  10. SQL Server 2008 数据库同步的两种方式 (发布、订阅)

    参考转载: SQL Server 2008 数据库同步的两种方式 (发布.订阅) 使用Sqlserver事务发布实现数据同步