2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018) Solution
A. Numbers
Unsolved.
B. Broken Watch
Solved.
题意:
一个圆盘上,有等分的n块区域,有三根指针,当三根指针分别位于两块区域的交界处时
指针的三点相连会形成一个三角形,求有多少个三角包含三指针的起点(即交汇处)
思路:
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull;
typedef long long ll; ll A, B, C, n; int main()
{
while(~scanf("%lld %lld %lld %lld" ,&A, &B, &C, &n))
{
ull tmp = (n + ) / ;
tmp -= ;
ull a = n, b = n - , c = n - ;
if(a % == ) a /= ;
else if(b % == ) b /= ;
else if(c % == ) c /= ; if(a % == ) a /= ;
else if(b % == ) b /= ;
else if(c % == ) c /= ; ull ans = a * b * c; ans -= n * (tmp * (tmp + ) / ); if(A != B && B != C && C != A) ans = ans * ;
else if(A != B || B != C || C != A) ans = ans * ; printf("%llu\n", ans);
}
return ;
}
C. Tree
Solved.
题意:
一棵树中,有些点是黑点,有些点是白点,求恰选择m个黑点
使得黑点中任意两点的最长距离最短
思路:
#include<bits/stdc++.h>
using namespace std;
const int maxn = ;
struct Edge{
int to, nxt;
Edge(){}
Edge(int to, int nxt): to(to), nxt(nxt){}
}edge[maxn << ];
int n, m;
int p[maxn];
int vis[maxn];
int head[maxn], tot;
void Init(int n)
{
tot = ;
for(int i = ; i <= n; ++i) head[i] = -;
}
void addedge(int u,int v)
{
edge[tot] = Edge(v, head[u]); head[u] = tot++;
edge[tot] = Edge(u, head[v]); head[v] = tot++;
}
int DFS(int u,int fa, int limit, int dis)
{
int res = p[u];
if(dis == limit) return res;
for(int i = head[u]; ~i; i = edge[i].nxt)
{
int v = edge[i].to;
if(!vis[v] || v == fa) continue;
res += DFS(v, u, limit, dis + );
}
return res;
}
bool check(int mid)
{
for(int i = ; i <= n; ++i) vis[i] = ;
queue<int>q;
q.push();
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = ;
if(DFS(u, -, mid, ) >= m) return true;
for(int i = head[u]; ~i; i = edge[i].nxt)
{
int v = edge[i].to;
if(vis[v]) continue;
q.push(v);
}
}
return false;
}
int main()
{
while(~scanf("%d %d", &n, &m))
{
Init(n);
for(int i = ; i <= n; ++i) scanf("%d", p + i);
for(int i = , u, v; i < n; ++i)
{
scanf("%d %d", &u, &v);
addedge(u, v);
}
int l = , r = n;
int res = ;
while(r - l >= )
{
int mid = (l + r) >> ;
if(check(mid))
{
r = mid - ;
res = mid;
}
else l = mid + ;
}
printf("%d\n", res);
}
return ;
}
D. Space Station
Unsolved.
E. Fishermen
Solved.
题意:
在一个二维平面,有有一些鱼,也有一些渔民,每个渔民有一个钓竿
渔民都在$x轴上,渔民可以钓到那条鱼的条件是它和鱼的曼哈顿距离小于等于钓竿长度$
思路:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + ;
struct node{
int l, r;
node(){}
node(int l,int r): l(l), r(r){}
bool operator < (const node &b) const
{
if(l == b.l) return r < b.r;
else return l < b.l;
}
}arr[maxn];
struct qnode{
int pos, idx;
qnode(){}
qnode(int pos, int idx): pos(pos), idx(idx){}
bool operator < (const qnode &b) const
{
return pos < b.pos;
}
}brr[maxn];
int n, m, l;
int ans[maxn];
int main()
{
while(~scanf("%d %d %d", &n, &m, &l))
{
int pos = ;
for(int i = ; i <= n; ++i)
{
int x, y;
scanf("%d %d", &x ,&y);
if(y > l) continue;
int tmp = l - y;
arr[++pos] = node(x - tmp, x + tmp);
}
sort(arr + , arr + + pos);
for(int i = ; i <= m; ++i)
{
scanf("%d", &brr[i].pos);
brr[i].idx = i;
}
sort(brr + , brr + + m);
priority_queue<int, vector<int>, greater<int> >q;
int cnt = ;
for(int i = ; i <= m; ++i)
{
while(cnt <= pos && brr[i].pos >= arr[cnt].l)
{
q.push(arr[cnt++].r);
}
while(!q.empty() && q.top() < brr[i].pos)
{
q.pop();
}
ans[brr[i].idx] = q.size();
}
for(int i = ; i <= m; ++i) printf("%d\n", ans[i]);
}
return ;
}
F. Min Max Convert
Unsolved.
题意:
每一次可以将一段区间的所有值变成它原先的最大或最小值
求有没有一种操作方案使得序列A 变成 序列B 如果有输出操作方案
否则输出-1
G. Matrix Queries
Unsolved.
题意:
在一个$2^n \cdot 2^n 的矩形里面,刚开始都是白色,每一次可以把一行或者一列的颜色翻转$
求每次操作后矩阵的值
这样定义矩阵的值:
如果当前矩阵的所有颜色都相同,那么该矩阵的值为1
否则将当前矩阵等分为四个,当前矩阵的值就是四个小矩阵的值+1
H. Modern Djinn
Unsolved.
I. Inversion
Solved.
题意:
在一张图中,求有多少个点集,使得这个点集里面的任意两点没有边
不在点集里面的点至少有一条边连向点集中一点
思路:
我们考虑一条边 $(i, j) 那么定义在一个序列中(i, j) 为一个逆序对$
那么就是找上升子序列的个数
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e2 + ; ll dp[maxn];
int G[maxn][maxn];
int n, m; int main()
{
while(~scanf("%d %d", &n, &m))
{
memset(dp, , sizeof dp);
memset(G, , sizeof G);
for(int i = , u, v; i <= m; ++i)
{
scanf("%d %d", &u, &v);
G[u][v]++;
G[v][u]++;
}
dp[] = ;
for(int i = ; i <= n + ; ++i)
{
for(int j = ; j < i; ++j)
{
if(G[i][j]) continue;
int flag = ;
for(int k = j + ; k < i; ++k)
{
if(G[i][k] || G[j][k]) continue;
else
{
flag = ;
break;
}
}
dp[i] += flag * dp[j];
}
}
printf("%lld\n", dp[n + ]);
}
return ;
}
J. Rabbit vs Turtle
Unsolved.
K. Points and Rectangles
Solved.
题意:
两种操作
一种是往一个二维平面加入一个点
还有一种是加入一个矩阵
询问每次操作后有多少个$pair(x, R)$
$pair(x, R) 表示 点x 在 矩形R 内$
思路:
考虑CDQ分治
对于每个矩阵,可以拆成四个点分治
对于每个点,我们可以把矩形的四个角赋上权值
左上角 1
左下角 -1
右上角-1
右下角1
然后把矩阵往左和网上拓宽一个单位
那么对于每个点来说就是查询右下角的值
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
struct qnode
{
int tp, x, y, id; bool isleft;
qnode () {}
qnode (int tp, int x, int y, int id) : tp(tp), x(x), y(y), id(id) {}
bool operator < (const qnode &other) const { return x < other.x || x == other.x && id < other.id; }
}que[N << ], tque[N << ];
int n, m, q, brr[N << ];
ll ans[N]; void Hash()
{
sort(brr + , brr + + m);
m = unique(brr + , brr + + m) - brr - ;
for (int i = ; i <= n; ++i) que[i].y = lower_bound(brr + , brr + + m, que[i].y) - brr;
} namespace BIT
{
int a[N << ];
void init() { memset(a, , sizeof a); }
void update(int x, int val)
{
for (; x <= m; x += x & -x)
{
if (val == ) a[x] = ;
else a[x] += val;
}
}
ll query(int x)
{
ll res = ;
for (; x; x -= x & -x)
res += a[x];
return res;
}
} void CDQ1(int l, int r)
{
if (l == r) return;
int mid = (l + r) >> ;
for (int i = l; i <= r; ++i)
{
tque[i] = que[i];
if (i <= mid) tque[i].isleft = true;
else tque[i].isleft = false;
}
sort(tque + l, tque + + r);
for (int i = l; i <= r; ++i)
{
if (tque[i].tp == && tque[i].isleft == true) BIT::update(tque[i].y, );
else if (tque[i].tp && tque[i].isleft == false)ans[tque[i].id] += BIT::query(tque[i].y) * tque[i].tp;
}
for (int i = l; i <= r; ++i) if (tque[i].tp == && tque[i].isleft == true) BIT::update(tque[i].y, );
CDQ1(l, mid), CDQ1(mid + , r);
} void CDQ2(int l, int r)
{
if (l == r) return;
int mid = (l + r) >> ;
for (int i = l; i <= r; ++i)
{
tque[i] = que[i];
if (i <= mid) tque[i].isleft = true;
else tque[i].isleft = false;
}
sort(tque + l, tque + + r, [](qnode a, qnode b) { return a.x > b.x || a.x == b.x && a.id < b.id; });
for (int i = l; i <= r; ++i)
{
if (tque[i].tp != && tque[i].isleft == true) BIT::update(tque[i].y, tque[i].tp);
else if (tque[i].tp == && tque[i].isleft == false) ans[tque[i].id] += BIT::query(m) - BIT::query(tque[i].y - );
}
for (int i = l; i <= r; ++i) if (tque[i].tp && tque[i].isleft == true) BIT::update(tque[i].y, );
CDQ2(l, mid); CDQ2(mid + , r);
} int main()
{
while (scanf("%d", &q) != EOF)
{
n = ; ans[] = ; m = ;
memset(ans, , sizeof ans);
for (int i = , op, x[], y[]; i <= q; ++i)
{
scanf("%d%d%d", &op, x, y);
brr[++m] = y[]; brr[++m] = y[] - ;
if (op == ) que[++n] = qnode(, x[], y[], i);
else
{
scanf("%d%d", x + , y + );
brr[++m] = y[]; brr[++m] = y[] - ;
que[++n] = qnode(, x[] - , y[] - , i);
que[++n] = qnode(, x[], y[], i);
que[++n] = qnode(-, x[] - , y[], i);
que[++n] = qnode(-, x[], y[] - , i);
}
}
Hash(); BIT::init();
CDQ1(, n); CDQ2(, n);
for (int i = ; i <= q; ++i) printf("%lld\n", ans[i] += ans[i - ]);
}
return ;
}
2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018) Solution的更多相关文章
- 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018)
layout: post title: 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 201 ...
- 2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017) Solution
A:Concerts 题意:给出一个串T, 一个串S,求串S中有多少个串T,可以重复,但是两个字符间的距离要满足给出的数据要求 思路:先顺序统计第一个T中的字符在S中有多少个,然后对于第二位的以及后面 ...
- 2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017)
2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017) 全靠 wxh的博客 补完这套.wx ...
- Gym 2009-2010 ACM ICPC Southwestern European Regional Programming Contest (SWERC 2009) A. Trick or Treat (三分)
题意:在二维坐标轴上给你一堆点,在x轴上找一个点,使得该点到其他点的最大距离最小. 题解:随便找几个点画个图,不难发现,答案具有凹凸性,有极小值,所以我们直接三分来找即可. 代码: int n; lo ...
- 2016-2017 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2016)
题目链接 Codefores_Gym_101164 Solved 6/11 Penalty Problem A Problem B Problem C Problem D Problem E Pr ...
- Southeastern European Regional Programming Contest 2019
easy: I medium-easy: BDEGJ medium: F medium-hard: A A. B. 按 x 排序,\(dp[i][j][k]\) 表示考虑前 \(i\) 个物品,lev ...
- ACM ICPC, Damascus University Collegiate Programming Contest(2018) Solution
A:Martadella Stikes Again 水. #include <bits/stdc++.h> using namespace std; #define ll long lon ...
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
A. Within Arm's Reach 留坑. B. Bribing Eve 枚举经过$1$号点的所有直线,统计直线右侧的点数,旋转卡壳即可. 时间复杂度$O(n\log n)$. #includ ...
- 2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
A. Arranging Hat $f[i][j]$表示保证前$i$个数字有序,修改了$j$次时第$i$个数字的最小值. 时间复杂度$O(n^3m)$. #include <bits/stdc+ ...
随机推荐
- 如何使用css影藏滚动条
1.单纯的一句代码: div ::-webkit-scrollbar {width: 0px;}//或者display:none 但是这代码最大的弊端就是只能在webkit内核的浏览器上进行显示,无法 ...
- 5个基于Web的建模工具
本文介绍 5 款很棒的直接可以在浏览器使用的建模工具,无需单独安装软件. 1. Creately提供在线图表和协助功能,包含多种建模语言(UML)支持,这里有一个简单的演示:here 2.Diagra ...
- 什么是"抓包"?怎样"抓包"?
你是网络管理员吗?你是不是有过这样的经历:在某一天的早上你突然发现网络性能急剧下降,网络服务不能正常提供,服务器访问速度极慢甚至不能访问,网络交换机端口指示灯疯狂地闪烁.网络出口处的路由器已经处于满负 ...
- office2010如何使用excel冻结窗格
当我们在制作一个Excel表格时,如果列数较多,行数也较多时,一旦向下滚屏,则上面的标题行也跟着滚动,在处理数据时往往难以分清各列数据对应的标题,事实上利用"冻结窗格"功能可以很好 ...
- python搭建简易Web Server
如果你急需一个简单的Web Server,但你又不想去下载并安装那些复杂的HTTP服务程序,比如:Apache,ISS等.那么, Python可能帮助你,使用Python可以完成一个简单的内建 HTT ...
- flash 逐字,逐行歌词实现,添加伪3D效果
项目结构: 效果如图: 项目为公司项目,下载人员禁止用于商业项目中. 项目开发工具:FlashDevelop 点击下载
- Flask中的session和cookie以及日志
一.笔记一session: 首先对于session在flask中应该是加密签名的cookie,所以要先生成secret_key app.secret_key = os.environ.get('SEC ...
- 【BZOJ2901】矩阵求和
Description 给出两个n*n的矩阵,m次询问它们的积中给定子矩阵的数值和. Input 第一行两个正整数n,m. 接下来n行,每行n个非负整数,表示第一个矩阵. 接下来n行,每行n个非负整数 ...
- 170531、FormData 对象的使用
通过FormData对象可以组装一组用 XMLHttpRequest发送请求的键/值对.它可以更灵活方便的发送表单数据,因为可以独立于表单使用.如果你把表单的编码类型设置为multipart/form ...
- ASP.NET网站性能优化
如果你是一个做过ASP网站,又做过ASP.NET网站的程序员,你可能会发现,如果按正常的思路开发ASP.NET网站,ASP.NET网站的速度会比ASP网站慢很多,为什么强大的网站语言会比弱得慢的,原因 ...