cf Round 607
A.Chain Reaction(DP+二分)
题意:一排有n个灯塔,每个灯塔给出坐标xi和力量yi,
每次从最右边依次点亮灯塔,每点亮一个灯塔,它左边的距离它yi范围内的灯塔将受到损坏。
现在允许在最右边>max(xi)处添加一座力量值yi的灯塔。
问最少只会损坏多少灯塔。
分析:因为我们是从右边点亮灯塔的,所以我们点亮我们添加的那座灯塔只会损坏连续个灯塔。最后就相当于从末尾的某一个灯塔开始点亮。
我们令dp[i]表示点亮第i座灯塔最少损坏多少灯塔。
于是我们对于每个dp[i],二分可以得到他前面的前驱。
所以dp[i]=dp[j]+1(j<i).
注意题目给出的灯塔并不是有序的,需要排序一遍。
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <math.h>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define MAXN
# define eps 1e-
# define MAXM
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
typedef unsigned long long ULL;
int _MAX(int a, int b){return a>b?a:b;}
int _MIN(int a, int b){return a>b?b:a;}
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
} int a[][], sum[]; int comp(const void * b, const void * c){return *(int *)b-*(int *)c;}
int main ()
{
int n;
scanf("%d",&n);
FOR(i,,n) scanf("%d%d",&a[i][],&a[i][]);
qsort(a+,n,sizeof(a[]),comp);
sum[]=;
FOR(i,,n) {
int l=, r=i, mid;
while (l<r) {
mid=(l+r)>>;
if (l==mid) break;
if (a[mid][]<a[i][]-a[i][]) l=mid;
else r=mid;
}
sum[i]=+sum[l];
}
int ans=;
FOR(i,,n) ans=max(ans,sum[i]);
printf("%d\n",n-ans);
return ;
}
B.Zuma(区间DP)
给出一串n个数字(n<=500).每次操作可以消掉一个回文串。然后补齐。
问最少需要操作多少次。
姿势很优雅的区间DP;
很容易想到dp[l][r]表示消掉[l,r]的回文串最少需要多少步。
但是在转移的过程中GG了,假如它先消中间的某一部分,然后再对齐再消,这样咋办。
于是我码了一个暴力判断字符串是否回文。结果TLE了。
仔细一想,因为1个数字显然是回文串。
对于[l,r]区间,我们枚举[l+1,r]内的一个k使得a[k]==a[l],这时候我们可以先消[l+1,k-1].
再消a[l]和a[k],我们注意到消[l+1,k-1]的最后一步一定会变成一个回文串,
因为a[l]==a[k], 所以我们消a[l,k]的步数就等于a[l+1,k-1].
即dp[l][k]==dp[l+1][k-1].
所以状态转移方程就是dp[l][r]=min(dp[l+1][r]+1,dp[l+1][k-1]+dp[k+1][r])(a[k]==a[l])
最后判断一下边界就行了。
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <math.h>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define MAXN
# define eps 1e-
# define MAXM
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
typedef unsigned long long ULL;
int _MAX(int a, int b){return a>b?a:b;}
int _MIN(int a, int b){return a>b?b:a;}
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
} int n, a[], dp[][]; int dfs(int l, int r)
{
if (~dp[l][r]) return dp[l][r];
if (l>r) return ;
if (l==r) return dp[l][r]=;
int ans=INF;
ans=min(ans,dfs(l+,r)+);
FOR(i,l+,r) {
if (a[i]==a[l]) {
if (i==r) ans=min(ans,dfs(l+,i-));
else if (i==l+) ans=min(ans,dfs(i+,r)+);
else ans=min(ans,dfs(l+,i-)+dfs(i+,r));
}
}
return dp[l][r]=ans;
}
int main ()
{
mem(dp,-);
scanf("%d",&n);
FOR(i,,n) scanf("%d",a+i);
dfs(,n);
printf("%d\n",dp[][n]);
return ;
}
C.Marbles(脑洞+hash)
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1E9+;
const int MI = ~0u>>; int main()
{
int n;
string s1,s2;
cin>>n>>s1>>s2;
n--;
for(int i=;i<n;i++)
{
switch(s2[i])
{
case 'N':s2[i]='S';break;
case 'S':s2[i]='N';break;
case 'W':s2[i]='E';break;
case 'E':s2[i]='W';break;
}
}
ULL v1=,v2=;
const ULL seed=;
ULL wt=;
for(int i=n-;i>=;i--,wt*=)
{
v1=v1+(s1[i]-'a')*wt;
v2=v2*seed+s2[i]-'a';
if(v1==v2)
{
printf("NO");
return ;
}
}
printf("YES");
return ;
}
D.Power Tree(线段树维护dfn+逆元)
分析: 我们可以算出每一个节点对根节点的贡献因子mi。
即di是节点i的儿子节点数+1.
实际上mi就是从i到根节点的简单路径上的di的乘积。
当新加入一个节点u到节点p时。我们观察可以发现,仅仅改变了p和p的子树的mi。
显然是mi=mi*(dp+1)/dp. mu=mp。
我们需要一个数据结构可以 对一个区间进行乘,更新一个值,以及求一个区间的总和。
我们用线段树维护dfn序。
那么一个节点的子树就是一段连续的区间。
我们求一个节点的贡献时。显然就是sum同时除以他们的公共路径的mi。
由于乘法是一个浮点数。我们先累乘所有的分子,再累乘所有的分母,最后我们用乘法逆元
可以求出取模。
代码量有点受不了。。。
#include <cstdio>
#include <vector>
#include <algorithm>
#pragma comment(linker, "/STACK:16000000")
using namespace std; typedef long long ll; const int mod = ;
const int Maxn = ;
const int Maxm = ; int n, q;
int val[Maxn];
int a[Maxn], b[Maxn], c[Maxn];
vector <int> neigh[Maxn];
int ch[Maxn];
int P[Maxn], cur, L[Maxn], R[Maxn];
int mult[Maxm];
int fl[Maxm], sum[Maxm]; void Traverse(int v)
{
L[v] = ++cur;
for (int i = ; i < neigh[v].size(); i++)
Traverse(neigh[v][i]);
R[v] = cur;
} void createMult(int v, int l, int r)
{
mult[v] = ;
if (l < r) {
int m = l + r >> ;
createMult( * v, l, m); createMult( * v + , m + , r);
}
} void updMult(int v, int l, int r, int a, int b, int val)
{
if (l == a && r == b) mult[v] = ll(mult[v]) * val % mod;
else {
int m = l + r >> ;
if (a <= m) updMult( * v, l, m, a, min(m, b), val);
if (m + <= b) updMult( * v + , m + , r, max(m + , a), b, val);
}
} int getMult(int v, int l, int r, int x)
{
int res = mult[v];
if (l < r) {
int m = l + r >> ;
if (x <= m) res = ll(res) * getMult( * v, l, m, x) % mod;
else res = ll(res) * getMult( * v + , m + , r, x) % mod;
}
return res;
} void Union(int v)
{
sum[v] = (sum[ * v] + sum[ * v + ]) % mod;
} void downOn(int v, int val)
{
fl[v] = ll(fl[v]) * val % mod;
sum[v] = ll(sum[v]) * val % mod;
} void Down(int v)
{
if (fl[v] != ) {
downOn( * v, fl[v]); downOn( * v + , fl[v]);
fl[v] = ;
}
} void createSum(int v, int l, int r)
{
fl[v] = ;
if (l == r) sum[v] = val[l];
else {
int m = l + r >> ;
createSum( * v, l, m); createSum( * v + , m + , r);
Union(v);
}
} int getSum(int v, int l, int r, int a, int b)
{
if (l == a && r == b) return sum[v];
else {
Down(v);
int m = l + r >> ;
int res = ;
if (a <= m) res = (res + getSum( * v, l, m, a, min(m, b))) % mod;
if (m + <= b) res = (res + getSum( * v + , m + , r, max(m + , a), b)) % mod;
return res;
}
} void multSum(int v, int l, int r, int a, int b, int val)
{
if (l == a && r == b) downOn(v, val);
else {
Down(v);
int m = l + r >> ;
if (a <= m) multSum( * v, l, m, a, min(m, b), val);
if (m + <= b) multSum( * v + , m + , r, max(m + , a), b, val);
Union(v);
}
} void addSum(int v, int l, int r, int x, int val)
{
if (l == r) sum[v] = val;
else {
Down(v);
int m = l + r >> ;
if (x <= m) addSum( * v, l, m, x, val);
else addSum( * v + , m + , r, x, val);
Union(v);
}
} int Inv(int a)
{
int p = mod - ;
int res = ;
while (p) {
if (p & ) res = ll(res) * a % mod;
p >>= ; a = ll(a) * a % mod;
}
return res;
} int main()
{
n = ; scanf("%d %d", &val[n], &q);
for (int i = ; i < q; i++) {
scanf("%d %d", &a[i], &b[i]);
if (a[i] == ) {
scanf("%d", &c[i]);
n++; P[n] = b[i];
neigh[b[i]].push_back(n);
}
}
Traverse();
createMult(, , R[]);
createSum(, , R[]);
n = ;
for (int i = ; i < q; i++)
if (a[i] == ) {
n++;
ch[b[i]]++;
int tomult = ll(ch[b[i]] + ) * Inv(ch[b[i]]) % mod;
updMult(, , R[], L[b[i]], R[b[i]], tomult);
multSum(, , R[], L[b[i]], R[b[i]], tomult);
val[n] = c[i];
tomult = getMult(, , R[], L[n]);
addSum(, , R[], L[n], ll(tomult) * val[n] % mod);
} else {
int res = getSum(, , R[], L[b[i]], R[b[i]]);
if (P[b[i]]) {
int tomult = Inv(getMult(, , R[], L[P[b[i]]]));
res = ll(res) * tomult % mod;
}
printf("%d\n", res);
}
return ;
}
E.Cross Sum(待填坑)
cf Round 607的更多相关文章
- CF Round #551 (Div. 2) D
CF Round #551 (Div. 2) D 链接 https://codeforces.com/contest/1153/problem/D 思路 不考虑赋值和贪心,考虑排名. 设\(dp_i\ ...
- CF Round #510 (Div. 2)
前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了..最后才\(A\)了\(3\) ...
- UOJ #30. [CF Round #278] Tourists
UOJ #30. [CF Round #278] Tourists 题目大意 : 有一张 \(n\) 个点, \(m\) 条边的无向图,每一个点有一个点权 \(a_i\) ,你需要支持两种操作,第一种 ...
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- 【前行&赛时总结】◇第4站&赛时9◇ CF Round 513 Div1+Div2
◇第4站&赛时9◇ CF Round 513 Div1+Div2 第一次在CF里涨Rating QWQ 深感不易……作blog以记之 ( ̄▽ ̄)" +Codeforces 的门为你打 ...
- CF Round #600 (Div 2) 解题报告(A~E)
CF Round #600 (Div 2) 解题报告(A~E) A:Single Push 采用差分的思想,让\(b-a=c\),然后观察\(c\)序列是不是一个满足要求的序列 #include< ...
- CF Round #580(div2)题解报告
CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...
- CF round #622 (div2)
CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...
- 【cf补题记录】Codeforces Round #607 (Div. 2)
比赛传送门 这里推荐一位dalao的博客-- https://www.cnblogs.com/KisekiPurin2019/ A:字符串 B:贪心 A // https://codeforces.c ...
随机推荐
- 12、ASP.NET MVC入门到精通——HtmlHelper
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 HtmlHelper:是为了方便View的开发而产生 HtmlHelper的演变 普通首页超级链接为:<a href="/h ...
- 利用SCORE法则来总结一次偷懒的单元测试过程
最近遇到一个单元测试的问题,本周正好学个了一个SCORE法则,这里正好练练手应用此法则将问题的前因后果分享给大家. S:背景 代码要有单元测试,检测的标准就是统计代码的单元测试覆盖率,程序员需要达到 ...
- lua-resty-websocket安装和测试
作者:杨鑫奇 关注Openresty很久了,期待支持websocket终于出来了,看到Aapo Talvensaari同学写的文章https://medium.com/p/1778601c9e05,兴 ...
- [deviceone开发]-do_ImageView实现正圆的示例
一.简介 我们经常需要用一个正圆形状的图片来设置头像,在do平台这个比较容易,就是通过设置圆角来实现,但是有几个小技巧需要解释一下 主要组件:do_ImageView 二.效果图 三.相关下载 htt ...
- javascript 中的location.href 并不是立即执行的,是在所在function 执行完之后执行的。
javascript 中的location.href 并不是立即执行的,是在所在function 执行完之后执行的. 1 function getUrl(tp) { if (tp == 'd') { ...
- php中用foreach改变数组的值的问题
翻到PHP文档的foreach那页这样写道: “foreach 语法结构提供了遍历数组的简单方式.foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误 ...
- atitit.农历的公式与原理以及农历日期运算
atitit.农历的公式与原理以及农历日期运算 1. 农历的概述1 2. 如何在电脑程序里面计算农历??1 3. 农历的公式2 4. 获取当日农历日历3 5. 历史日期公式加查表才能得到精确日期3 6 ...
- VS2012 Unit Test —— 我对接口进行单元测试使用的技巧
[题外话] 对单元测试不熟悉的童鞋可参照我之前写过的两篇博文: <在Visual Studio 2012使用单元测试>. <VS2012 单元测试之泛型类(Generics Unit ...
- shell脚步传参
linux系统除了提供位置参数还提供内置参数,内置参数如下: $# ----传递给程序的总的参数数目 $? ----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非 ...
- IOS基础之UILineBreakModeWordWrap
UILineBreakModeWordWrap详细解释如下: typedef enum { UILineBreakModeWordWrap = 0, UILineBreakModeC ...