codeforces Educational Codeforces Round 65 (补完)
C News Distribution
并查集水题
D Bicolored RBS
括号匹配问题,如果给出的括号序列nesting depth为n,那么最终可以分成两个nesting depth为n / 2的序列。
在进行匹配的时候,如果当前栈中的左括号大于等于 n / 2,那么剩下的括号就要进行标记,最终标记和不标记的分成两个部分。
E Range Deleting
对一个序列去掉一个区间范围内的数字,使得剩下的序列是一个非降序的序列。
这题是一道较好的思维题。
首先可以预处理出1到\(pref\),只保留\([1,pref]\)内的数字,序列是非降序的;也可以预处理出\(suf\)到\(x\),保留\([suf,x]\)内的数字,序列是非降序的。
然后可以发现,如果去掉\([l,r]\)满足条件,那么去掉\([l,r+1],[l,r+2],...,[l,x]\)也一定是满足条件的。
可以枚举\(l\),枚举的范围是\([1,pref+1]\),\(pref+1\)是因为\([1,pref]\)的序列都是有序的,所以去掉\(pref+1\)也是有序的;对于每一个\(l\),要找出满足条件的\(r\)的数量;
因为去掉了\(l\)到某个数字,前面剩下的数字就是\([1,l-1]\),那么\(r\)满足的条件就是首先要大于等于\(suf\),大于等于\(l\),然后还要满足在\([1,l-1]\)当中出现的最大的数字的最后一个下标之前,这个数字没有出现过,换个角度,假设\([1,l-1]\)当中出现的最大的数字的最后一个下标是\(ind\),那么\(r\)的最小值就是\(max(a[1],....,a[ind])+1\),于是\(r\)的最小值就由之前的3个条件共同求出,满足条件的\(r\)的个数就分为两种情况:
1.\(l == r\),那么就有\(x - r + 1\)种;
2.\(l != r\),那么就有\(x - r + 2\)种,因为\(r\)是可以保留在序列当中的,所以可以去掉的范围是\([r-1,x]\),也就是说去掉\([l,r-1]\)这个区间也是满足条件的。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 10;
vector<int> G[N];
set<int> s;
int pre[N],sub[N];
int a[N];
bool L[N],R[N];
int main()
{
int n,x;
scanf("%d%d",&n,&x);
for (int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
s.insert(a[i]);
}
if (x == 1)
{
puts("1");
return 0;
}
pre[0] = -inf;
for (int i = 1;i <= n;i++)
{
pre[i] = max(pre[i-1],a[i]);
}
sub[n+1] = inf;
for (int i = n;i >= 1;i--)
{
sub[i] = min(sub[i+1],a[i]);
}
for (int i = 1;i <= n;i++)
{
G[a[i]].push_back(i);
}
int pref,suf;
L[1] = 1;
for (int i = 2;i <= x;i++)
{
if (G[i].empty())
{
L[i] = L[i-1];
}
else
{
int p = G[i][0];
int x = sub[p];
if (x < i)
{
L[i] = 0;
}
else
{
L[i] = L[i-1];
}
}
}
R[x] = 1;
for (int i = x - 1;i >= 1;i--)
{
if (G[i].empty())
{
R[i] = R[i+1];
}
else
{
int sz = G[i].size();
int p = G[i][sz-1];
int x = pre[p];
if (x > i)
{
R[i] = 0;
}
else
{
R[i] = R[i+1];
}
}
}
for (int i = 1;i <= x;i++)
{
if (L[i]) pref = i;
}
for (int i = x;i >= 1;i--)
{
if (R[i]) suf = i;
}
ll ans = 0;
for (int i = 1;i <= x;i++)
{
if (i == 1)
{
for (int j = 1;j <= x;j++)
{
if (R[j+1])
{
ans += x - j + 1;
//printf("%d *\n",x - j + 1);
break;
}
}
}
else
{
if (!L[i-1]) break;
int l = i-1;
if (l < (*s.begin()) || l > (*--s.end()))
{
int tmp = max(l + 1,suf);
if (tmp == l + 1)
{
ans += x - tmp + 1;
}
else
{
ans += x - tmp + 2;
//printf("%d *\n",x - tmp + 2);
}
}
else
{
if (G[l].empty())
{
int xx = *--s.lower_bound(l);
int sz = G[xx].size();
int p = G[xx][sz-1];
int tmp = max(pre[p] + 1,suf);
tmp = max(l + 1,tmp);
if (tmp == l + 1)
{
ans += x - tmp + 1;
}
else
{
ans += x - tmp + 2;
}
}
else
{
int sz = G[l].size();
int p = G[l][sz-1];
int tmp = max(pre[p] + 1,suf);
if (tmp == l + 1)
{
ans += x - tmp + 1;
}
else
{
ans += x - tmp + 2;
}
}
}
}
}
printf("%lld\n",ans);
return 0;
}
F Scalar Queries
题意:
有一个数组\(a\),里面的数字两两不同,\(f(l,r)\)表示选出下标从\(l\)到\(r\)的数字,然后排序,排序之后的数组为\(b\),\(\sum_{i = 1}^{r - l + 1}b_i * i\)。
需要求每一个\(f(l,r)\)的和。
思路:
又是一道很好的思维题。
可以转化为求每一个数字对最终答案的贡献。
假设\(low(l,r,a[i])\)表示在区间\([l,r]\)内小于\(a[i]\)的数字,那么\(a[i]\)对于\((l,r)\)的贡献就是\(a[i] * low(l,r,a[i])+1\)。
\(low(l,r,a[i])+1\)就相当于\(a[i]\)在\((l,r)\)内的rank。
这个rank又转化为每一个小于\(a[i]\)的数字出现的次数之和。
首先对于\(a_i\)本身,它自己出现的次数是\(i * (n - i - 1)\);
然后对于\(a_j < a_i,j < i\)的数字,它的出现次数是\(j * (n - i + 1)\);
对于\(a_j < a_i,j > i\)的数字,它的出现次数是\(i * (n - j + 1)\);
如上三个数字相加,假设为\(sum\),那么\(sum * a_i\)就是\(a_i\)对答案的贡献。
对于小于某个数字的所有数字出现的位置,可以用树状数组求前缀和。大的也同理。
又出现了\(int * int\) 爆\(int\) 的问题!!!
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 5e5 + 10;
const ll mod = 1000000000LL + 7;
ll c[N],d[N];
int n;
int lowbit(int x)
{
return x&(-x);
}
void addl(int x,int y)
{
for (int i = x;i <= n;i += lowbit(i)) c[i] += y;
}
void addr(int x,int y)
{
for (int i = x;i <= n;i += lowbit(i)) d[i] += y;
}
ll getlsum(int x)
{
ll ans = 0;
for (int i = x;i >= 1;i -= lowbit(i))
{
ans += c[i];
ans %= mod;
}
return ans;
}
ll getrsum(int x)
{
ll ans = 0;
for (int i = x;i >= 1;i -= lowbit(i))
{
ans += d[i];
ans %= mod;
}
return ans;
}
pii a[N];
int main()
{
scanf("%d",&n);
for (int i = 1;i <= n;i++)
{
scanf("%d",&a[i].first);
a[i].second = i;
}
sort(a+1,a+1+n);
ll ans = 0;
for (int i = 1;i <= n;i++)
{
ll x = getlsum(a[i].second);
ll tmp = 0;
tmp += x * (n-a[i].second+1);
tmp %= mod;
ll y = getrsum(n-a[i].second+1);
tmp += y * a[i].second;
tmp %= mod;
tmp += 1LL * a[i].second * (n-a[i].second + 1);
tmp %= mod;
ans += tmp * a[i].first;
ans %= mod;
addl(a[i].second,a[i].second);
addr(n-a[i].second + 1,n-a[i].second+1);
}
ans += mod;
printf("%lld\n",ans % mod);
return 0;
}
codeforces Educational Codeforces Round 65 (补完)的更多相关文章
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...
- codeforces Educational Codeforces Round 5 A. Comparing Two Long Integers
题目链接:http://codeforces.com/problemset/problem/616/A 题目意思:顾名思义,就是比较两个长度不超过 1e6 的字符串的大小 模拟即可.提供两个版本,数组 ...
- Codeforces Educational Codeforces Round 3 A. USB Flash Drives 水题
A. USB Flash Drives 题目连接: http://www.codeforces.com/contest/609/problem/A Description Sean is trying ...
- codeforces Educational Codeforces Round 16-E(DP)
题目链接:http://codeforces.com/contest/710/problem/E 题意:开始文本为空,可以选择话费时间x输入或删除一个字符,也可以选择复制并粘贴一串字符(即长度变为两倍 ...
- Codeforces Educational Codeforces Round 15 E - Analysis of Pathes in Functional Graph
E. Analysis of Pathes in Functional Graph time limit per test 2 seconds memory limit per test 512 me ...
- Codeforces Educational Codeforces Round 15 D. Road to Post Office
D. Road to Post Office time limit per test 1 second memory limit per test 256 megabytes input standa ...
- Codeforces Educational Codeforces Round 15 C. Cellular Network
C. Cellular Network time limit per test 3 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Educational Codeforces Round 5 E. Sum of Remainders 数学
E. Sum of Remainders 题目连接: http://www.codeforces.com/contest/616/problem/E Description The only line ...
随机推荐
- LeetCode.1170-比较字符串中最小字符的出现频率(Compare Strings by Frequency of the Smallest Char)
这是小川的第412次更新,第444篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第263题(顺位题号是1170).在一个非空字符串s上定义一个函数f(s),该函数计算s中最小字 ...
- Java 基础篇之泛型
背景 在没有泛型前,一旦把一个对象丢进集合中,集合就会忘记对象的类型,把所有的对象都当成 Object 类型处理.当程序从集合中取出对象后,就需要进行强制类型转换,这种转换很容易引起 ClassCas ...
- 现代化的拷贝文字---clipboard.js
参考链接:http://www.clipboardjs.cn/
- 11个顶级 JavaScript 日历插件
参考链接:https://mp.weixin.qq.com/s?__biz=MzI3NzIzMDY0NA==&mid=2247487050&idx=1&sn=e1cf66726 ...
- POJ1703Find them, Catch them 【种类并查集】
题目链接:http://poj.org/problem?id=1703 题目大意:给n个人,m次询问.A代表询问a, b之间的关系,D代表给出a, b属于不同的帮派. 我的想法: 太菜了,上课的时候没 ...
- [Comet OJ - Contest #6 C][48C 2279]一道树题_树
一道树题 题目大意: 给定一棵树,边的编号为读入顺序.现在规定,区间$[L, R]$的贡献$S(L,R)$为把编号在该区间里的边都连上后,当前形成的森林中点数大于等于$2$的联通块个数. 求$\sum ...
- C++命名建议
如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套统一.带层次结构.清晰明了的命名准则就是必不可少而且非常好用的工具. 活跃在生物学.化学.军队.监狱.黑社会.恐怖组织等各个领域内的大量有识 ...
- 论文笔记-IGCV3:Interleaved Low-Rank Group Convolutions for Efficient Deep Neural Networks
论文笔记-IGCV3:Interleaved Low-Rank Group Convolutions for Efficient Deep Neural Networks 2018年07月11日 14 ...
- Hinton等人最新研究:大幅提升模型准确率,标签平滑技术到底怎么用?
Hinton等人最新研究:大幅提升模型准确率,标签平滑技术到底怎么用? 2019年07月06日 19:30:55 AI科技大本营 阅读数 675 版权声明:本文为博主原创文章,遵循CC 4.0 B ...
- Java深入分析类与对象
深入分析类与对象 1,成员属性封装 在类之中的组成就是属性与方法,一般而言方法都是对外提供服务的,所以是不会进行封装处理的,而对于属性需要较高的安全性,所以往往需要对其进行保护,这个时候就需要采用封装 ...