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 题解的更多相关文章

  1. AtCoder Grand Contest 015题解

    传送门 \(A\) 找到能达到的最大的和最小的,那么中间任意一个都可以被表示出来 typedef long long ll; int n,a,b;ll res; int main(){ scanf(& ...

  2. AtCoder Grand Contest 017 题解

    A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...

  3. AtCoder Grand Contest 015 C - Nuske vs Phantom Thnook

    题目传送门:https://agc015.contest.atcoder.jp/tasks/agc015_c 题目大意: 现有一个\(N×M\)的矩阵\(S\),若\(S_{i,j}=1\),则该处为 ...

  4. AtCoder Grand Contest 015 E - Mr.Aoki Incubator

    题目传送门:https://agc015.contest.atcoder.jp/tasks/agc015_e 题目大意: 数轴上有\(N\)个点,每个点初始时在位置\(X_i\),以\(V_i\)的速 ...

  5. Atcoder Grand Contest 015 F - Kenus the Ancient Greek(找性质+乱搞)

    洛谷题面传送门 & Atcoder 题面传送门 一道难度 Au 的 AGC F,虽然看过题解之后感觉并不复杂,但放在现场确实挺有挑战性的. 首先第一问很简单,只要每次尽量让"辗转相除 ...

  6. Atcoder Grand Contest 054 题解

    那天晚上由于毕业晚会与同学吃饭喝酒没打 AGC,第二天稍微补了下题,目前补到了 E,显然 AGC 的 F 对于我来说都是不可做题就没补了(bushi A 简单题,不难发现如果我们通过三次及以上的操作将 ...

  7. AtCoder Grand Contest 015

    传送门 A - A+...+B Problem 题意:n个数最大值a,最小值b,求和的可能数量. #include<cstdio> #include<algorithm> us ...

  8. AtCoder Grand Contest 030题解

    第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...

  9. AtCoder Grand Contest 031题解

    题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...

随机推荐

  1. EasyNVR无插件H5/HLS/m3u8直播解决方案中Windows系统服务启动错误问题的修复:EasyNVR_Service 服务因 函数不正确。 服务特定错误而停止。

    最近在做某地市移动公司景观直播的项目时,遇到一个问题,当我们部署EasyNVR为系统服务后,居然出现了无法启动服务的现象,表面上看,提示是系统服务启动失败,实际通过查看windows 系统日志: 查找 ...

  2. zabbix_get 命令介绍

    zabbix_get 是 zabbix 服务端的一个命令,用于检测 agent 端的配置是否正确,可以很方便地知道 key 是否能正常获取到数据,在测试自定义监控的时候特别有用 [root@crazy ...

  3. Openstack 架构简述

    概述 在学习OpenStack的过程中,感觉对整个OpenStack的架构稍稍有些了解,所以将这些记录下来,一来防止自己忘记,二来也可以对有需要的人提供帮助 本文章相关的灵感/说明/图片来自于http ...

  4. mssql-在一个特定的会话停止出发器

    用SET CONTEXT_INFO来实现 --在某个会话里设置 SET CONTEXT_INFO 0x8888 --在触发器里判断 ) SELECT @Cinfo = Context_Info() 原 ...

  5. Flex自定义组件开发

    一般情况下需要组件重写都是由于以下2个原因:1.在FLEX已有组件无法满足业务需求,或是需要更改其可视化外观等特性时,直接进行继承扩展.2.为了模块化设计或进一步重用,需要对FLEX组件进行组合.而F ...

  6. shiro1

    基于角色的访问控制 RBAC(role based access control),基于角色的访问控制. 比如: 系统角色包括 :部门经理.总经理.(角色针对用户来划分) 系统代码中实现: //如果该 ...

  7. js之定时器

    一.通过定时器我们可以间隔设定时间重复调用某个函数,利用这个特性,我们可以做很多事,例如,12306上的每间隔5秒查询自动查询一次余票,简单动画的实现等等 二.定时器的格式: 定时器有两种格式,分别是 ...

  8. systemverilog FAQ(zz)

    1. What is clocking block? Ans: Clocking block can be declared using the keywords clocking and endcl ...

  9. WebSocket实现Web聊天室

    一.客户端: JS代码如下: /* * 这部分js将websocket封装起来 */ var websocket = null; //判断当前浏览器是否支持WebSocket if ('WebSock ...

  10. 《python基础教程(第二版)》学习笔记 字符串(第3章)

    <python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:格式化输出字符 ...