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 ...
随机推荐
- iOS下Audio自动播放(Autoplay)音乐
前几天做了一个H5活动页面,产品要求初始化播放音乐,因晓得H5 Audio标签支持Autoplay就没在意. 完了在手机上测试,发现手机上打开页面死活就是不会自动播放,点击播放按钮才可以播放,很是纠结 ...
- Android开发3:Intent、Bundle的使用和ListView的应用 、RelativeLayout(相对布局)简述(简单通讯录的实现)
前言 啦啦啦~博主又来骚扰大家啦~大家是不是感觉上次的Android开发博文有点长呢~主要是因为博主也是小白,在做实验的过程中查询了很多很多概念,努力去理解每一个知识点,才完成了最终的实验.还有就是随 ...
- Linux0.11内核--文件系统理论知识
1.文件系统介绍 一个简单的文件系统大致需要这么几个要素: ● 要有地方存放Metadata: ● 要有地方记录扇区的使用情况: ● 要有地方来记录任一文件的信息,比如占用了哪些扇区等: ● 要有地方 ...
- -bash: ulimit: pipe size: cannot modify limit: Invalid argument
从root账号切换到oracle账号时,出现了"-bash: ulimit: pipe size: cannot modify limit: Invalid argument"提示 ...
- PHP服务缓存优化之ZendOpcache、xcache、eAccelerator
PHP服务缓存优化原理 Nginx 根据扩展名或者过滤规则将PHP程序请求传递给解析PHP的FCGI,也就是php-fpm进程 缓存操作码(opcode) Opcode,PHP编译后的中间文件,缓存给 ...
- 聊下 git 使用前的一些注意事项
连接方式https.ssh 在使用git的时候,不管你的服务器是开源平台github还是私服gitlab,你都需要clone仓库到本地,这个clone的时候就需要你选择连接方式.这个连接方式决定了你与 ...
- 大数据系列(3)——Hadoop集群完全分布式坏境搭建
前言 上一篇我们讲解了Hadoop单节点的安装,并且已经通过VMware安装了一台CentOS 6.8的Linux系统,咱们本篇的目标就是要配置一个真正的完全分布式的Hadoop集群,闲言少叙,进入本 ...
- eclipse编辑jsp保存的时候特别卡解决办法
今天eclipse用着用着的时候,每次编辑jsp页面快捷键保存的时候要等半天才保存好,特别的卡.搞的很蛋疼.上网搜了下有解决办法 Window -> Preference -> Gener ...
- shell中export理解误区
一直以来,以为shell脚本中经过export后的变量会影响到执行这个shell的终端中的环境变量.环境变量这个概念不是shell所独有的,而是linux里面进程所拥有的,shell解释器运行起来就是 ...
- 腾讯 Bugly for Xamarin Android 的插件
因为项目中需要异常控制,所以在 gpyer bugly 等 Bug 收集平台中选择,最后选定了 Bugly. 于是将 Bugly 的插件 进行了 Java Binding,打成了 Xamarin 可用 ...