AtCoder Grand Contest 015 题解
A - A+...+B Problem 常识
Problem Statement
Snuke has N integers. Among them, the smallest is A, and the largest is B. We are interested in the sum of those N integers. How many different possible sums there are?
用\(n\)个在\([A,B]\)之间的数加和能够组合出来的不同的数的个数.
Constraints
- \(1 \leq N,A,B \leq 10^9\)
- A and B are integers.
Solution
常识
#include <cstdio>
#include <cstring>
typedef long long ll;
int main(){
int n,a,b;scanf("%d%d%d",&n,&a,&b);
ll l = 1LL*a*(n-1) + b,r = 1LL*b*(n-1) + a;
if(l > r) {puts("0");return 0;}
else printf("%lld\n",(r-l+1));
return 0;
}
B - Evilator 贪心
Problem Statement
Skenu constructed a building that has N floors. The building has an elevator that stops at every floor.
There are buttons to control the elevator, but Skenu thoughtlessly installed only one button on each floor - up or down. This means that, from each floor, one can only go in one direction. If Si is U, only "up" button is installed on the i-th floor and one can only go up; if Si is D, only "down" button is installed on the i-th floor and one can only go down.
The residents have no choice but to go to their destination floors via other floors if necessary. Find the sum of the following numbers over all ordered pairs of two floors (i,j): the minimum number of times one needs to take the elevator to get to the j-th floor from the i-th floor.
一个\(n\)层高的楼有一个电梯,在每一层时只有'U'和'D'两种按钮中的一个按钮.
'U'按钮可以到达任意一个大于当前楼层的层数.'D'按钮类似.
设\(dis(u,v)\)表示从\(u\)层到\(v\)层按按钮的最小次数
求\(\sum_{i=1}^n\sum_{j=1}^ndis(i,j)\)
Constraints
- \(2 \leq |S| \leq 105\)
- \(S_i\) is either U or D.
- \(S_1\) is U.
- \(S_{|S|}\) is D.
Solution
可以考虑枚举每一层,然后计算出该层到所有层的距离.
对于某一层,如果按钮为'D',那么到以下的所有楼层只需要按一次按钮.
到上面的楼层的话,只要向下找到一个向上的按钮就好了,所以只需要按两次按钮.
统计每一层,求和即为答案.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 100010;
char s[maxn];
int main(){
scanf("%s",s+1);
int n = strlen(s+1);
ll ans = 0;
rep(i,1,n){
if(s[i] == 'U') ans += (n-i) + ((i-1)<<1);
else ans += (i-1) + ((n-i)<<1);
}printf("%lld\n",ans);
return 0;
}
C - Nuske vs Phantom Thnook 思维题
Problem Statement
Nuske has a grid with N rows and M columns of squares. The rows are numbered 1 through N from top to bottom, and the columns are numbered 1 through M from left to right. Each square in the grid is painted in either blue or white. If Si,j is 1, the square at the i-th row and j-th column is blue; if Si,j is 0, the square is white. For every pair of two blue square a and b, there is at most one path that starts from a, repeatedly proceeds to an adjacent (side by side) blue square and finally reaches b, without traversing the same square more than once.
Phantom Thnook, Nuske's eternal rival, gives Q queries to Nuske. The i-th query consists of four integers xi,1, yi,1, xi,2 and yi,2 and asks him the following: when the rectangular region of the grid bounded by (and including) the xi,1-th row, xi,2-th row, yi,1-th column and yi,2-th column is cut out, how many connected components consisting of blue squares there are in the region?
Process all the queries.
给定一个\(n*m\)的网格图。每个格子有\(0/1\)两种颜色,保证任意两个\(1\)的格子最多有一条路径连接它们.
每次询问一个矩形区域内\(1\)格子的联通块的数目。
题目中所有联通都是四联块
Constraints
- \(1 \leq N,M \leq 2000\)
- \(1 \leq Q \leq 200000\)$
- \(S_{i,j}\) is either 0 or 1.
- \(S_{i,j}\) satisfies the condition explained in the statement.
- \(1 \leq xi,1 \leq xi,2 \leq N(1 \leq i \leq Q)\)
- \(1 \leq yi,1 \leq yi,2 \leq M(1 \leq i \leq Q)\)
Solution
这道题乍一看我还以为是 [APIO 2017] 的题.
不过两道题有所不同,APIO的题诗保证总体的块都是连通的。
而这道题保证的是所有的块的联通方式组成了一片森林。
而对于森林来说,联通块的个数即点数减去边数.
所以统计一下格子内\(1\)的块数和边数即可.
利用二维前缀和可以做到\(O(n^2)\)预处理\(O(1)\)实现查询.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 2048;
const int maxm = 100010;
char s[maxn][maxn];
int sum_node[maxn][maxn];
int sum_edgex[maxn][maxn];
int sum_edgey[maxn][maxn];
int n,m;
inline void init(){
rep(i,1,n) rep(j,1,m){
if(s[i][j] == '1') sum_node[i][j] = 1;
else sum_node[i][j] = 0;
sum_node[i][j] += sum_node[i-1][j] + sum_node[i][j-1] - sum_node[i-1][j-1];
}
rep(i,1,n) rep(j,1,m){
if(s[i][j] == '1' && s[i-1][j] == '1') sum_edgex[i][j] = 1;
else sum_edgex[i][j] = 0;
if(s[i][j] == '1' && s[i][j-1] == '1') sum_edgey[i][j] = 1;
else sum_edgey[i][j] = 0;
sum_edgex[i][j] += sum_edgex[i-1][j] + sum_edgex[i][j-1] - sum_edgex[i-1][j-1];
sum_edgey[i][j] += sum_edgey[i-1][j] + sum_edgey[i][j-1] - sum_edgey[i-1][j-1];
}
}
inline int calc(int x2,int y2,int x1,int y1,int s[2048][2048]){
return s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1];
}
int main(){
read(n);read(m);int q;read(q);
rep(i,1,n) scanf("%s",s[i]+1);
init();
int x1,x2,y1,y2;
while(q--){
read(x1);read(y1);read(x2);read(y2);
if(x1 > x2) swap(x1,x2);
if(y1 > y1) swap(y1,y2);
int ans = 0;
ans -= calc(x2,y2,x1,y1+1,sum_edgey);
ans -= calc(x2,y2,x1+1,y1,sum_edgex);
ans += calc(x2,y2,x1,y1,sum_node);
printf("%d\n",ans);
}
return 0;
}
D - A or...or B Problem
Problem Statement
Nukes has an integer that can be represented as the bitwise OR of one or more integers between A and B (inclusive). How many possible candidates of the value of Nukes's integer there are?
用\(n\)个在\([A,B]\)之间的数 位或 能够组合出来的不同的数的个数.
Constraints
- \(1\leq A\leq B<260\)
- \(A\) and \(B\) are integers.
Solution
既然这道题要求的是位或后的到的值。
那么我们就将\(A,B\)转化成二进制去思考。
首先从高到低找到一个\(A,B\)不相同的二进制位,设为第\(r\)位
那么所有大于该二进制位的位都是没有用处的.可以直接删除.
这时我们把所有的数分成两个集合:
\(X : [A,2^r), Y : [2^r,B]\)
如果设\(k\)为\(B\)中第一个小于\(r\)的为\(1\)的二进制位.那么有:
- 只用\(X\)集合的数可以组合出 : \([A,2^r)\)
- 只用\(Y\)集合的数可以组合出 : \([2^r,2^r+2^{k+1}-1]\)
- 必须同时使用\(X,Y\)集合的数可以组合出 : \([2^r+A,2^{r+1}-1]\)
所以直接加上\([A,2^{r+1}-1]\)再判一下\((2^r+2^{k+1}-1)和(2^r+A)\)的关系减一下就好了.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(ll &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
int main(){
ll A,B;read(A);read(B);
if(A == B){
puts("1");
return 0;
}
ll r,k;
for(r = 60;(A & (1LL << r)) == (B & ( 1LL << r));-- r);
A &= (1LL << (r+1)) - 1;B &= (1LL << (r+1)) - 1;
ll ans = (1LL << r+1) - A;
for(k = r-1;k >= 0 && (B & (1LL << k)) == 0;-- k);
if(A > (1LL << k+1)) ans -= A - (1LL << k+1);
printf("%lld\n",ans);
return 0;
}
E - Mr.Aoki Incubator
Problem Statement
Takahashi is an expert of Clone Jutsu, a secret art that creates copies of his body.
On a number line, there are N copies of Takahashi, numbered 1 through N. The i-th copy is located at position Xi and starts walking with velocity Vi in the positive direction at time 0.
Kenus is a master of Transformation Jutsu, and not only can he change into a person other than himself, but he can also transform another person into someone else.
Kenus can select some of the copies of Takahashi at time 0, and transform them into copies of Aoki, another Ninja. The walking velocity of a copy does not change when it transforms. From then on, whenever a copy of Takahashi and a copy of Aoki are at the same coordinate, that copy of Takahashi transforms into a copy of Aoki.
Among the 2N ways to transform some copies of Takahashi into copies of Aoki at time 0, in how many ways will all the copies of Takahashi become copies of Aoki after a sufficiently long time? Find the count modulo 109+7.
给定一个数轴上的\(n\)各点及他们的速度,定义红色点和黑色点在某一刻相遇时黑色点会变成红色.
问有多少种初始红点的选取方案使得无限长的时间后所有点都是红色.
Constraints
- \(1\leq N\leq 200000\)
- \(1\leq Xi,Vi\leq 109(1\leq i\leq N)\)
- \(X_i\) and \(V_i\) are integers.
- All \(X_i\) are distinct.
- All \(V_i\) are distinct.
Solution:
这道题好神啊.
首先考虑两点相遇的条件,设为\(i,j\).
则有:
- \(x_i < x_j \text{且} v_i > v_j\)
- \(x_i > x_j \text{且} v_i < v_j\)
那么假设说我们将所有的点按照他们的速度排序.
然后设\(L_i\)表示点\(i\)左侧最靠左\(x\)值大于\(x_i\)的点.
相应的设\(R_i\)表示点\(i\)右侧最靠右的\(x\)值小于\(x_i\)的点.
容易发现如果选取了第\(i\)个点,那么\([L_i,R_i]\)中的点都会被染色.
然后就可以将问题转化为选取若干组区间覆盖整个区间.
容易发现所有区间都不会存在包含关系.
所以可以按照拓扑图进行\(dp\).
\(S\)连向所有左端点为\(1\),所有右端点为\(n\)的点连向\(T\).
两个区间\(i,j\space (i<j)\)若\(L_j \leq R_i+1\)则连一条\(i \to j\)的边.
连出来的图一定是\(DAG\),所以在\(DAG\)上跑路径计数即可.
但是这个\(DAG\)明显不能直接建出来,因为边数太大了.
但是我们可以直接在这个序列上跑\(dp\),用线段树优化\(dp\)即可.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 200010;
const int mod = 1e9+7;
int Tmx[maxn<<2],Tmn[maxn<<2],T[maxn<<2];
void modify(int rt,int l,int r,int pos,int val){
if(l == r){
Tmx[rt] = Tmn[rt] = val;
T[rt] += val;
if(T[rt] >= mod) T[rt] -= mod;
return ;
}
int mid = (l+r) >> 1;
if(pos <= mid) modify(rt<<1,l,mid,pos,val);
else modify(rt<<1|1,mid+1,r,pos,val);
Tmx[rt] = max(Tmx[rt<<1],Tmx[rt<<1|1]);
Tmn[rt] = min(Tmn[rt<<1],Tmn[rt<<1|1]);
T[rt] = T[rt<<1] + T[rt<<1|1];if(T[rt] >= mod) T[rt] -= mod;
}
int query_min(int rt,int l,int r,int L,int R){
if(L <= l && r <= R) return Tmn[rt];
int mid = (l+r) >> 1;
if(R <= mid) return query_min(rt<<1,l,mid,L,R);
if(L > mid) return query_min(rt<<1|1,mid+1,r,L,R);
return min(query_min(rt<<1,l,mid,L,R),query_min(rt<<1|1,mid+1,r,L,R));
}
int query_max(int rt,int l,int r,int L,int R){
if(L <= l && r <= R) return Tmx[rt];
int mid = (l+r) >> 1;
if(R <= mid) return query_max(rt<<1,l,mid,L,R);
if(L > mid) return query_max(rt<<1|1,mid+1,r,L,R);
return max(query_max(rt<<1,l,mid,L,R),query_max(rt<<1|1,mid+1,r,L,R));
}
int query_sum(int rt,int l,int r,int L,int R){
if(L <= l && r <= R) return T[rt];
int mid = (l+r) >> 1;
if(R <= mid) return query_sum(rt<<1,l,mid,L,R);
if(L > mid) return query_sum(rt<<1|1,mid+1,r,L,R);
return (query_sum(rt<<1,l,mid,L,R) + query_sum(rt<<1|1,mid+1,r,L,R)) % mod;
}
struct Node{
int x,v;
bool friend operator < (const Node &a,const Node &b){
return a.v < b.v;
}
}a[maxn];
struct seg{
int L,R;
bool friend operator < (const seg &a,const seg &b){
return a.R == b.R ? a.L < b.L : a.R < b.R;
}
}se[maxn];
int seq[maxn];
int main(){
int n;read(n);
rep(i,1,n){
read(a[i].x);read(a[i].v);
seq[i] = a[i].x;
}sort(seq+1,seq+n+1);sort(a+1,a+n+1);
rep(i,1,n){
a[i].x = lower_bound(seq+1,seq+n+1,a[i].x) - seq;
}
memset(Tmn,0x3f,sizeof Tmn);
rep(i,1,n){
if(a[i].x+1 <= n) se[i].L = query_min(1,1,n,a[i].x+1,n);
else se[i].L = i;
se[i].L = min(se[i].L,i);
modify(1,1,n,a[i].x,i);
}
memset(Tmx,0,sizeof Tmx);
per(i,n,1){
if(a[i].x-1 >= 1) se[i].R = query_max(1,1,n,1,a[i].x-1);
else se[i].R = i;
se[i].R = max(se[i].R,i);
modify(1,1,n,a[i].x,i);
}
sort(se+1,se+n+1);
memset(T,0,sizeof T);
int ans = 0;
per(i,n,1){
int res = 0;
if(se[i].R == n) res ++ ;
res += query_sum(1,1,n,1,min(se[i].R+1,n));
if(res >= mod) res -= mod;
modify(1,1,n,se[i].L,res);
if(se[i].L == 1) ans += res;
if(ans >= mod) ans -= mod;
}printf("%d\n",ans);
return 0;
}
AtCoder Grand Contest 015 题解的更多相关文章
- AtCoder Grand Contest 015题解
传送门 \(A\) 找到能达到的最大的和最小的,那么中间任意一个都可以被表示出来 typedef long long ll; int n,a,b;ll res; int main(){ scanf(& ...
- AtCoder Grand Contest 017 题解
A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...
- AtCoder Grand Contest 015 C - Nuske vs Phantom Thnook
题目传送门:https://agc015.contest.atcoder.jp/tasks/agc015_c 题目大意: 现有一个\(N×M\)的矩阵\(S\),若\(S_{i,j}=1\),则该处为 ...
- AtCoder Grand Contest 015 E - Mr.Aoki Incubator
题目传送门:https://agc015.contest.atcoder.jp/tasks/agc015_e 题目大意: 数轴上有\(N\)个点,每个点初始时在位置\(X_i\),以\(V_i\)的速 ...
- Atcoder Grand Contest 015 F - Kenus the Ancient Greek(找性质+乱搞)
洛谷题面传送门 & Atcoder 题面传送门 一道难度 Au 的 AGC F,虽然看过题解之后感觉并不复杂,但放在现场确实挺有挑战性的. 首先第一问很简单,只要每次尽量让"辗转相除 ...
- Atcoder Grand Contest 054 题解
那天晚上由于毕业晚会与同学吃饭喝酒没打 AGC,第二天稍微补了下题,目前补到了 E,显然 AGC 的 F 对于我来说都是不可做题就没补了(bushi A 简单题,不难发现如果我们通过三次及以上的操作将 ...
- AtCoder Grand Contest 015
传送门 A - A+...+B Problem 题意:n个数最大值a,最小值b,求和的可能数量. #include<cstdio> #include<algorithm> us ...
- AtCoder Grand Contest 030题解
第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...
- AtCoder Grand Contest 031题解
题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...
随机推荐
- 去除app中的标题栏
我之前一直用的是在oncreate方法中添加 requestWindowFeature(Window.FEATURE_NO_TITLE),并且必须写在setContentView(R.layout.a ...
- Mysql 行数据转换为列数据
现有如下表: 需要统计手机所有售卖价格,显示为如下表: 需要使用group_concat对price进行处理,并且去重重复价格 sql如下: select type,group_concat(DIST ...
- json:js和jquery中轻量级数据交换格式
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族 ...
- android菜鸟学习笔记22----ContentProvider(二)ContentObserver的简单使用
现在有这样一个应用A通过ContentProvider提供自己的数据给其他应用,应用B通过ContentResolver获取应用A中提供的数据,并将其展示在ListView中,而应用C通过Conten ...
- iphone传感器
传感器 什么是传感器 传感器是一种感应\检测装置, 目前已经广泛应用于智能手机上 传感器的作用 用于感应\检测设备周边的信息 不同类型的传感器, 检测的信息也不一样 iPhone中的下面现象都是由传感 ...
- activiti--6-------------------------------------连线(一般数据库表的查询顺序)
一.流程图 二.这次把流程图和Java类放在一个包下 三.代码 package com.xingshang.f_sequenceFlow; import java.io.InputStream; im ...
- Iptalbes练习题(二)
接着上节,上节课,基本功能设置后,现在我们telnet本机一下,发现问题: [root@test1 ~]# telnet Trying 127.0.0.1... telnet: connect to ...
- zabbix实现mysql数据库的监控(三)
上面一章“zabbix实现mysql数据库的监控(二)”使用MPM来监控mysql,但是遇到安装问题始终解决不了,这里改用percona-monitoring-plugins进行zabbxi上监控my ...
- 文字溢出 省略css
overflow:hidden; text-overflow:ellipsis; -o-text-overflow:ellipsis; white-space:nowrap;
- 光流法跟踪fast角点思路
光流法需要include<opencv2/video/tracking.hpp>,用到列表,所以要include<list><vector>1.读取文件定义图像存储 ...